1564 lines
46 KiB
HTML
1564 lines
46 KiB
HTML
<!doctype html>
|
|
<head><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script>
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="http://localhost:1313/css/main.min.f77a4050bafcd273d43d6737e174f344bd91a213d9bc92b097cb31fc7dbe1cb9.css">
|
|
</head>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#f7f7f7">
|
|
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1b1b1e">
|
|
<meta name="mobile-web-app-capable" content="yes">
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
|
<meta
|
|
name="viewport"
|
|
content="width=device-width, user-scalable=no, initial-scale=1, shrink-to-fit=no, viewport-fit=cover"
|
|
>
|
|
|
|
<meta property="og:url" content="http://localhost:1313/post/2024-09-21-websitedeployment/">
|
|
<meta property="og:site_name" content="Comprofix">
|
|
<meta property="og:title" content="Continuous Integration & Continuous Deployment">
|
|
<meta property="og:description" content="Since the reset of the website, I have been working on getting it to auto build and deploy using Gitea Actions. Which is similar and compatible to GitHub Actions
|
|
Before implementing the action it was a manual process which required using docker commands to login, build and push the image to the container registry.
|
|
Why use CI/CD? It takes the manual process steps away and does them for you, helping you to avoid missing any steps and avoiding errors. This also makes the interaction seamless and automated.">
|
|
<meta property="og:locale" content="en">
|
|
<meta property="og:type" content="article">
|
|
<meta property="article:section" content="post">
|
|
<meta property="article:published_time" content="2024-09-21T00:00:00+00:00">
|
|
<meta property="article:modified_time" content="2024-09-21T00:00:00+00:00">
|
|
<meta property="article:tag" content="Homelab">
|
|
<meta property="article:tag" content="Git">
|
|
<meta property="article:tag" content="Docker">
|
|
<meta property="article:tag" content="Ci">
|
|
<meta property="article:tag" content="Cd">
|
|
<meta property="article:tag" content="Continuous Integration">
|
|
|
|
|
|
<meta name="twitter:card" content="summary">
|
|
<meta name="twitter:title" content="Continuous Integration & Continuous Deployment">
|
|
<meta name="twitter:description" content="Since the reset of the website, I have been working on getting it to auto build and deploy using Gitea Actions. Which is similar and compatible to GitHub Actions
|
|
Before implementing the action it was a manual process which required using docker commands to login, build and push the image to the container registry.
|
|
Why use CI/CD? It takes the manual process steps away and does them for you, helping you to avoid missing any steps and avoiding errors. This also makes the interaction seamless and automated.">
|
|
|
|
|
|
<meta itemprop="name" content="Continuous Integration & Continuous Deployment">
|
|
<meta itemprop="description" content="Since the reset of the website, I have been working on getting it to auto build and deploy using Gitea Actions. Which is similar and compatible to GitHub Actions
|
|
Before implementing the action it was a manual process which required using docker commands to login, build and push the image to the container registry.
|
|
Why use CI/CD? It takes the manual process steps away and does them for you, helping you to avoid missing any steps and avoiding errors. This also makes the interaction seamless and automated.">
|
|
<meta itemprop="datePublished" content="2024-09-21T00:00:00+00:00">
|
|
<meta itemprop="dateModified" content="2024-09-21T00:00:00+00:00">
|
|
<meta itemprop="wordCount" content="539">
|
|
<meta itemprop="keywords" content="Homelab,Git,Docker,Ci,Cd,Continuous Integration,Continuous Deployment">
|
|
|
|
<title>
|
|
|
|
Continuous Integration & Continuous Deployment |
|
|
|
|
Comprofix
|
|
</title>
|
|
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/img/favicons/apple-touch-icon.png">
|
|
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicons/favicon-32x32.png">
|
|
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicons/favicon-16x16.png">
|
|
|
|
<link rel="shortcut icon" href="/img/favicons/favicon.ico">
|
|
<meta name="apple-mobile-web-app-title" content="Comprofix">
|
|
<meta name="application-name" content="Comprofix">
|
|
<meta name="msapplication-TileColor" content="#da532c">
|
|
<meta name="msapplication-config" content="/img/favicons/browserconfig.xml">
|
|
<meta name="theme-color" content="#ffffff">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" >
|
|
|
|
<link rel="dns-prefetch" href="https://fonts.googleapis.com" >
|
|
|
|
|
|
|
|
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
|
|
<link rel="dns-prefetch" href="https://fonts.gstatic.com" >
|
|
|
|
|
|
|
|
|
|
<link rel="preconnect" href="https://cdn.jsdelivr.net" >
|
|
|
|
<link rel="dns-prefetch" href="https://cdn.jsdelivr.net" >
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="http://localhost:1313/css/main.min.f77a4050bafcd273d43d6737e174f344bd91a213d9bc92b097cb31fc7dbe1cb9.css">
|
|
|
|
|
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Lato:wght@300;400&family=Source+Sans+Pro:wght@400;600;700;900&display=swap">
|
|
|
|
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.7.1/css/all.min.css">
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tocbot@4.32.2/dist/tocbot.min.css">
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="/">
|
|
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/glightbox@3.3.0/dist/css/glightbox.min.css">
|
|
|
|
|
|
|
|
<script src="/js/modules/theme.js"></script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/glightbox@3.3.0/dist/js/glightbox.min.js"></script>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js"></script>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/dayjs@1.11.13/dayjs.min.js"></script>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/dayjs@1.11.13/locale/en.js"></script>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/dayjs@1.11.13/plugin/relativeTime.js"></script>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/dayjs@1.11.13/plugin/localizedFormat.js"></script>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/tocbot@4.32.2/dist/tocbot.min.js"></script>
|
|
|
|
|
|
|
|
|
|
|
|
<script defer src="/js/post.js"></script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</head>
|
|
<body>
|
|
|
|
<aside aria-label="Sidebar" id="sidebar" class="d-flex flex-column align-items-end">
|
|
<header class="profile-wrapper">
|
|
<a href="/" id="avatar" class="rounded-circle"><img src="/img/man-logo.png" width="112" height="112" alt="avatar" onerror="this.style.display='none'"></a>
|
|
|
|
<a class="site-title d-block" href="/">Comprofix</a>
|
|
|
|
<p class="site-subtitle fst-italic mb-0">Geek | Nerd | Systems Administrator | IT Specialist</p>
|
|
|
|
</header>
|
|
|
|
|
|
<nav class="flex-column flex-grow-1 w-100 ps-0">
|
|
<ul class="nav">
|
|
|
|
|
|
|
|
<li class="nav-item">
|
|
<a href="/" class="nav-link">
|
|
<i class="fa-fw fas fa-house"></i>
|
|
<span>HOME</span>
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
<li class="nav-item">
|
|
<a href="/categories/" class="nav-link">
|
|
<i class="fa-fw fas fa-stream"></i>
|
|
<span>CATEGORIES</span>
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
<li class="nav-item">
|
|
<a href="/tags/" class="nav-link">
|
|
<i class="fa-fw fas fa-tags"></i>
|
|
<span>TAGS</span>
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
<li class="nav-item">
|
|
<a href="/archives/" class="nav-link">
|
|
<i class="fa-fw fas fa-archive"></i>
|
|
<span>ARCHIVES</span>
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
<li class="nav-item">
|
|
<a href="/about/" class="nav-link">
|
|
<i class="fa-fw fas fa-info-circle"></i>
|
|
<span>ABOUT</span>
|
|
</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
<div class="sidebar-bottom d-flex flex-wrap align-items-center w-100">
|
|
|
|
<button type="button" class="btn btn-link nav-link" aria-label="Switch Mode" id="mode-toggle">
|
|
<i class="fas fa-adjust"></i>
|
|
</button>
|
|
|
|
|
|
<span class="icon-border"></span>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a
|
|
href="https://git.comprofix.com/mmckinnon"
|
|
aria-label="custom"
|
|
target="_blank" rel="noopener noreferrer"
|
|
|
|
>
|
|
<i class="fab fa-git-alt"></i>
|
|
</a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a
|
|
href="https://twitter.com/mckinnon81"
|
|
aria-label="twitter"
|
|
target="_blank" rel="noopener noreferrer"
|
|
|
|
>
|
|
<i class="fab fa-twitter"></i>
|
|
</a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a
|
|
href="http://localhost:1313/index.xml"
|
|
aria-label="rss"
|
|
|
|
|
|
>
|
|
<i class="fas fa-rss"></i>
|
|
</a>
|
|
|
|
|
|
</div>
|
|
|
|
</aside>
|
|
|
|
<div id="main-wrapper" class="d-flex justify-content-center">
|
|
<div class="container d-flex flex-column px-xxl-5">
|
|
|
|
<header id="topbar-wrapper" class="flex-shrink-0" aria-label="Top Bar">
|
|
<div id="topbar" class="d-flex align-items-center justify-content-between px-lg-3 h-100">
|
|
<nav id="breadcrumb" aria-label="Breadcrumb">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<span>
|
|
<a href="/">Home</a>
|
|
</span>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<span>Continuous Integration & Continuous Deployment</span>
|
|
|
|
|
|
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
<button type="button" id="sidebar-trigger" class="btn btn-link" aria-label="Sidebar">
|
|
<i class="fas fa-bars fa-fw"></i>
|
|
</button>
|
|
|
|
<div id="topbar-title">
|
|
Continuous Integration & Continuous Deployment
|
|
</div>
|
|
|
|
<button type="button" id="search-trigger" class="btn btn-link" aria-label="Search">
|
|
<i class="fas fa-search fa-fw"></i>
|
|
</button>
|
|
|
|
<search id="search" class="align-items-center ms-3 ms-lg-0">
|
|
<i class="fas fa-search fa-fw"></i>
|
|
<input
|
|
class="form-control"
|
|
id="search-input"
|
|
type="search"
|
|
aria-label="search"
|
|
autocomplete="off"
|
|
placeholder="Search..."
|
|
>
|
|
</search>
|
|
<button type="button" class="btn btn-link text-decoration-none" id="search-cancel">Cancel</button>
|
|
</div>
|
|
</header>
|
|
<div class="row flex-grow-1">
|
|
<main aria-label="Main Content" class="col-12 col-lg-11 col-xl-9 px-md-4">
|
|
|
|
|
|
|
|
|
|
|
|
<article class="px-1" data-toc="true">
|
|
<header>
|
|
<h1 data-toc-skip>Continuous Integration & Continuous Deployment</h1>
|
|
|
|
|
|
<div class="post-meta text-muted">
|
|
|
|
<span>
|
|
Posted
|
|
|
|
|
|
|
|
|
|
<time
|
|
|
|
data-ts="1726876800"
|
|
data-df="ll"
|
|
data-bs-toggle="tooltip" data-bs-placement="bottom"
|
|
>
|
|
%b %e, %Y
|
|
</time>
|
|
</span>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="mt-3 mb-3">
|
|
<img src="/post/2024-09-21-websitedeployment/devops.png" class="preview-img" alt="Preview Image" w="1200" h="630" ></div>
|
|
|
|
|
|
<div class="d-flex justify-content-between">
|
|
|
|
<span>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
By
|
|
|
|
<em>
|
|
|
|
|
|
|
|
Comprofix
|
|
|
|
|
|
|
|
|
|
</em>
|
|
</span>
|
|
|
|
<div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<span
|
|
class="readtime"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="bottom"
|
|
title="1460 words"
|
|
>
|
|
<em>8 min</em> read</span>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
|
|
<div id="toc-bar" class="d-flex align-items-center justify-content-between invisible">
|
|
<span class="label text-truncate">Continuous Integration & Continuous Deployment</span>
|
|
<button type="button" class="toc-trigger btn me-1">
|
|
<i class="fa-solid fa-list-ul fa-fw"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<button id="toc-solo-trigger" type="button" class="toc-trigger btn btn-outline-secondary btn-sm">
|
|
<span class="label ps-2 pe-1">Contents</span>
|
|
<i class="fa-solid fa-angle-right fa-fw"></i>
|
|
</button>
|
|
|
|
<dialog id="toc-popup" class="p-0">
|
|
<div class="header d-flex flex-row align-items-center justify-content-between">
|
|
<div class="label text-truncate py-2 ms-4">Continuous Integration & Continuous Deployment</div>
|
|
<button id="toc-popup-close" type="button" class="btn mx-1 my-1 opacity-75">
|
|
<i class="fas fa-close"></i>
|
|
</button>
|
|
</div>
|
|
<div id="toc-popup-content" class="px-4 py-3 pb-4"><nav id="TableOfContents">
|
|
<ul>
|
|
<li>
|
|
<ul>
|
|
<li><a href="#why-use-cicd">Why use CI/CD?</a></li>
|
|
<li><a href="#setting-up-the-aciton">Setting up the Aciton</a></li>
|
|
<li><a href="#buildyml-explained">build.yml explained</a></li>
|
|
<li><a href="#gitea-action-completes">Gitea Action Completes</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</nav></div>
|
|
</dialog>
|
|
|
|
|
|
<div class="content">
|
|
|
|
|
|
|
|
|
|
|
|
<p>Since the reset of the website, I have been working on getting it to auto build and deploy using <a href="https://docs.gitea.com/usage/actions/overview">Gitea Actions</a>. Which is similar and compatible to <a href="https://github.com/features/actions">GitHub Actions</a></p>
|
|
<p>Before implementing the action it was a manual process which required using docker commands to login, build and push the image to the container registry.</p>
|
|
<h3 id="why-use-cicd" id=why-use-cicd>
|
|
|
|
<span class="me-2">Why use CI/CD?</span>
|
|
<a href="#why-use-cicd" class="anchor text-muted"><i class="fas fa-hashtag"></i></a>
|
|
|
|
</h3><p>It takes the manual process steps away and does them for you, helping you to avoid missing any steps and avoiding errors. This also makes the interaction seamless and automated.</p>
|
|
<h3 id="setting-up-the-aciton" id=setting-up-the-aciton>
|
|
|
|
<span class="me-2">Setting up the Aciton</span>
|
|
<a href="#setting-up-the-aciton" class="anchor text-muted"><i class="fas fa-hashtag"></i></a>
|
|
|
|
</h3><p>To setup the action we first needed to create some “secrets” in the repo. Secrets are secure variables that are requied to interact with systems. Such as passwords, usernames, SSH Keys etc.</p>
|
|
<a href="/post/2024-09-21-websitedeployment/gitea-secrets.png" class="popup img-link ">
|
|
<img src="/post/2024-09-21-websitedeployment/gitea-secrets.png" alt="gitea secrets">
|
|
</a><p>After populating our secrets file we can then create our <code>.gitea/workflows/build.yml</code> file. This file contains all the steps to build, test and deploy the container.</p>
|
|
<p>{% raw %}</p>
|
|
<div class="code-block">
|
|
<div class="code-header"> <span data-label-text="YAML"><i class="fas fa-code fa-fw small"></i></span> <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div>
|
|
|
|
<div class="highlight"><div class="chroma">
|
|
<table class="lntable"><tr><td class="lntd">
|
|
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
|
</span><span class="lnt"> 2
|
|
</span><span class="lnt"> 3
|
|
</span><span class="lnt"> 4
|
|
</span><span class="lnt"> 5
|
|
</span><span class="lnt"> 6
|
|
</span><span class="lnt"> 7
|
|
</span><span class="lnt"> 8
|
|
</span><span class="lnt"> 9
|
|
</span><span class="lnt">10
|
|
</span><span class="lnt">11
|
|
</span><span class="lnt">12
|
|
</span><span class="lnt">13
|
|
</span><span class="lnt">14
|
|
</span><span class="lnt">15
|
|
</span><span class="lnt">16
|
|
</span><span class="lnt">17
|
|
</span><span class="lnt">18
|
|
</span><span class="lnt">19
|
|
</span><span class="lnt">20
|
|
</span><span class="lnt">21
|
|
</span><span class="lnt">22
|
|
</span><span class="lnt">23
|
|
</span><span class="lnt">24
|
|
</span><span class="lnt">25
|
|
</span><span class="lnt">26
|
|
</span><span class="lnt">27
|
|
</span><span class="lnt">28
|
|
</span><span class="lnt">29
|
|
</span><span class="lnt">30
|
|
</span><span class="lnt">31
|
|
</span><span class="lnt">32
|
|
</span><span class="lnt">33
|
|
</span><span class="lnt">34
|
|
</span><span class="lnt">35
|
|
</span><span class="lnt">36
|
|
</span><span class="lnt">37
|
|
</span><span class="lnt">38
|
|
</span><span class="lnt">39
|
|
</span><span class="lnt">40
|
|
</span><span class="lnt">41
|
|
</span><span class="lnt">42
|
|
</span><span class="lnt">43
|
|
</span><span class="lnt">44
|
|
</span><span class="lnt">45
|
|
</span><span class="lnt">46
|
|
</span><span class="lnt">47
|
|
</span><span class="lnt">48
|
|
</span><span class="lnt">49
|
|
</span><span class="lnt">50
|
|
</span><span class="lnt">51
|
|
</span><span class="lnt">52
|
|
</span><span class="lnt">53
|
|
</span></code></pre></td>
|
|
<td class="lntd">
|
|
<pre tabindex="0" class="chroma"><code class="language-yml" data-lang="yml"><span class="line"><span class="cl"><span class="nt">on</span><span class="p">:</span><span class="w"> </span><span class="l">push</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">jobs</span><span class="p">:</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">build-node</span><span class="p">:</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-latest</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">container</span><span class="p">:</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">catthehacker/ubuntu:act-latest</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">steps</span><span class="p">:</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">checkout repo</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v4</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Use Node.js</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/setup-node@v4</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Install Node Dependencies</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l">npm ci</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Build 11ty Site</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l">npm run build --if-present</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Set up Docker Buildx</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">docker/setup-buildx-action@v3</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Login to DockerHub</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">docker/login-action@v3</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">registry</span><span class="p">:</span><span class="w"> </span><span class="l">git.comprofix.com</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">username</span><span class="p">:</span><span class="w"> </span><span class="l">${{ secrets.REGISTRY_USERNAME }}</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">password</span><span class="p">:</span><span class="w"> </span><span class="l">${{ secrets.REGISTRY_TOKEN }}</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Build and push</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">docker/build-push-action@v6</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">context</span><span class="p">:</span><span class="w"> </span><span class="l">./</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">file</span><span class="p">:</span><span class="w"> </span><span class="l">./Dockerfile</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">push</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">tags</span><span class="p">:</span><span class="w"> </span><span class="l">git.comprofix.com/mmckinnon/comprofix.com:latest</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">publish</span><span class="p">:</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-latest</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">steps</span><span class="p">:</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">checkout repo</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v4</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Publish Website</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
|
|
</span></span></span><span class="line"><span class="cl"><span class="sd"> mkdir ~/.ssh
|
|
</span></span></span><span class="line"><span class="cl"><span class="sd"> echo "${{ secrets.SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
|
|
</span></span></span><span class="line"><span class="cl"><span class="sd"> chmod 644 ~/.ssh/known_hosts
|
|
</span></span></span><span class="line"><span class="cl"><span class="sd"> eval $(ssh-agent -s)
|
|
</span></span></span><span class="line"><span class="cl"><span class="sd"> ssh-add <(echo "${{ secrets.SSH_PRIVATE_KEY }}")
|
|
</span></span></span><span class="line"><span class="cl"><span class="sd"> ssh administrator@comprofix.com "cd /opt/comprofix; docker compose down" || true
|
|
</span></span></span><span class="line"><span class="cl"><span class="sd"> scp docker-compose.yml administrator@comprofix.com:/opt/comprofix
|
|
</span></span></span><span class="line"><span class="cl"><span class="sd"> ssh administrator@comprofix.com "cd /opt/comprofix; docker compose pull; docker compose up -d"</span></span></span></code></pre></td></tr></table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<p>{% endraw %}</p>
|
|
<h3 id="buildyml-explained" id=buildyml-explained>
|
|
|
|
<span class="me-2">build.yml explained</span>
|
|
<a href="#buildyml-explained" class="anchor text-muted"><i class="fas fa-hashtag"></i></a>
|
|
|
|
</h3><ul>
|
|
<li>
|
|
<div class="code-block">
|
|
<div class="code-header"> <span data-label-text="YAML"><i class="fas fa-code fa-fw small"></i></span> <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div>
|
|
|
|
<div class="highlight"><div class="chroma">
|
|
<table class="lntable"><tr><td class="lntd">
|
|
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
|
</span></code></pre></td>
|
|
<td class="lntd">
|
|
<pre tabindex="0" class="chroma"><code class="language-yml" data-lang="yml"><span class="line"><span class="cl"><span class="nt">on</span><span class="p">:</span><span class="w"> </span><span class="l">push</span></span></span></code></pre></td></tr></table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
This tells the action to run when code is pushed to the repo.</li>
|
|
<li>
|
|
<div class="code-block">
|
|
<div class="code-header"> <span data-label-text="YAML"><i class="fas fa-code fa-fw small"></i></span> <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div>
|
|
|
|
<div class="highlight"><div class="chroma">
|
|
<table class="lntable"><tr><td class="lntd">
|
|
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
|
</span><span class="lnt">2
|
|
</span><span class="lnt">3
|
|
</span></code></pre></td>
|
|
<td class="lntd">
|
|
<pre tabindex="0" class="chroma"><code class="language-yml" data-lang="yml"><span class="line"><span class="cl"><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-latest</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">container</span><span class="p">:</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">catthehacker/ubuntu:act-latest</span></span></span></code></pre></td></tr></table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
This specified the “container” to use to run all the steps on. This was crucial as running without a “conatiner” would fail as not all required dependencies where available</li>
|
|
<li>
|
|
<div class="code-block">
|
|
<div class="code-header"> <span data-label-text="YAML"><i class="fas fa-code fa-fw small"></i></span> <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div>
|
|
|
|
<div class="highlight"><div class="chroma">
|
|
<table class="lntable"><tr><td class="lntd">
|
|
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
|
</span><span class="lnt">2
|
|
</span><span class="lnt">3
|
|
</span><span class="lnt">4
|
|
</span></code></pre></td>
|
|
<td class="lntd">
|
|
<pre tabindex="0" class="chroma"><code class="language-yml" data-lang="yml"><span class="line"><span class="cl"><span class="nt">jobs</span><span class="p">:</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">build-node</span><span class="p">:</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="l">...</span><span class="w">
|
|
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="l">publish:</span></span></span></code></pre></td></tr></table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
These are the names of the separate jobs for the build action. The build node will build the site and create the new docker container and push to the registry. The publish will connect the host running the container and restart using the new container.</li>
|
|
<li>
|
|
<div class="code-block">
|
|
<div class="code-header"> <span data-label-text="YAML"><i class="fas fa-code fa-fw small"></i></span> <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div>
|
|
|
|
<div class="highlight"><div class="chroma">
|
|
<table class="lntable"><tr><td class="lntd">
|
|
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
|
</span></code></pre></td>
|
|
<td class="lntd">
|
|
<pre tabindex="0" class="chroma"><code class="language-yml" data-lang="yml"><span class="line"><span class="cl"><span class="l">steps:</span></span></span></code></pre></td></tr></table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
Each job has a list of steps it performs on the code. Most of these a pretty self explaining on what they do. Everything from check out the code. Setup Node environment and build. Run the docker commands to login to the registry, build the container and push. Then the last job steps connect the host and pull the new container and start.</li>
|
|
</ul>
|
|
<h3 id="gitea-action-completes" id=gitea-action-completes>
|
|
|
|
<span class="me-2">Gitea Action Completes</span>
|
|
<a href="#gitea-action-completes" class="anchor text-muted"><i class="fas fa-hashtag"></i></a>
|
|
|
|
</h3><p>Once the new code was commited to the repo the Action was able to complete successfully.</p>
|
|
<a href="/post/2024-09-21-websitedeployment/gitea-action-successful.png" class="popup img-link ">
|
|
<img src="/post/2024-09-21-websitedeployment/gitea-action-successful.png" alt="">
|
|
</a>
|
|
</div>
|
|
|
|
<div class="post-tail-wrapper text-muted">
|
|
|
|
|
|
<div class="post-meta mb-3">
|
|
<i class="far fa-folder-open fa-fw me-1"></i>
|
|
|
|
|
|
|
|
|
|
<a href="/categories/homelab/">homelab</a>
|
|
|
|
,
|
|
|
|
|
|
|
|
|
|
<a href="/categories/homelab/gitea/">gitea</a>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="post-tags">
|
|
<i class="fa fa-tags fa-fw me-1"></i>
|
|
|
|
<a
|
|
href="/tags/homelab/"
|
|
class="post-tag no-text-decoration"
|
|
>homelab</a>
|
|
|
|
<a
|
|
href="/tags/git/"
|
|
class="post-tag no-text-decoration"
|
|
>git</a>
|
|
|
|
<a
|
|
href="/tags/docker/"
|
|
class="post-tag no-text-decoration"
|
|
>docker</a>
|
|
|
|
<a
|
|
href="/tags/ci/"
|
|
class="post-tag no-text-decoration"
|
|
>ci</a>
|
|
|
|
<a
|
|
href="/tags/cd/"
|
|
class="post-tag no-text-decoration"
|
|
>cd</a>
|
|
|
|
<a
|
|
href="/tags/continuous-integration/"
|
|
class="post-tag no-text-decoration"
|
|
>continuous integration</a>
|
|
|
|
<a
|
|
href="/tags/continuous-deployment/"
|
|
class="post-tag no-text-decoration"
|
|
>continuous deployment</a>
|
|
|
|
</div>
|
|
|
|
|
|
<div class="post-tail-bottom d-flex justify-content-between align-items-center mt-5 pb-2">
|
|
<div class="license-wrapper">
|
|
|
|
|
|
This post is licensed under <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a> by the author.
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</article>
|
|
|
|
</main>
|
|
|
|
|
|
<aside aria-label="Panel" id="panel-wrapper" class="col-xl-3 ps-2 text-muted">
|
|
<div class="access">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<section id="access-lastmod">
|
|
<h2 class="panel-heading">Recently Updated</h2>
|
|
<ul class="content list-unstyled ps-0 pb-1 ms-1 mt-2">
|
|
|
|
|
|
|
|
|
|
<li class="text-truncate lh-lg">
|
|
<a href="/post/2024-09-21-websitedeployment/">Continuous Integration & Continuous Deployment</a>
|
|
</li>
|
|
|
|
|
|
|
|
|
|
<li class="text-truncate lh-lg">
|
|
<a href="/post/2024-09-05-resetrestart/">Reset and Restart</a>
|
|
</li>
|
|
|
|
</ul>
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<section>
|
|
<h2 class="panel-heading">Trending Tags</h2>
|
|
<div class="d-flex flex-wrap mt-3 mb-1 me-3">
|
|
|
|
|
|
<a class="post-tag btn btn-outline-primary" href="http://localhost:1313/tags/cd/">cd</a>
|
|
|
|
|
|
<a class="post-tag btn btn-outline-primary" href="http://localhost:1313/tags/ci/">ci</a>
|
|
|
|
|
|
<a class="post-tag btn btn-outline-primary" href="http://localhost:1313/tags/continuous-deployment/">continuous deployment</a>
|
|
|
|
|
|
<a class="post-tag btn btn-outline-primary" href="http://localhost:1313/tags/continuous-integration/">continuous integration</a>
|
|
|
|
|
|
<a class="post-tag btn btn-outline-primary" href="http://localhost:1313/tags/docker/">docker</a>
|
|
|
|
|
|
<a class="post-tag btn btn-outline-primary" href="http://localhost:1313/tags/git/">git</a>
|
|
|
|
|
|
<a class="post-tag btn btn-outline-primary" href="http://localhost:1313/tags/homelab/">homelab</a>
|
|
|
|
</div>
|
|
</section>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="toc-border-cover z-3"></div>
|
|
<section id="toc-wrapper" class="invisible position-sticky ps-0 pe-4 pb-4">
|
|
<h2 class="panel-heading ps-3 pb-2 mb-0">Contents</h2>
|
|
<nav id="toc"></nav>
|
|
</section>
|
|
|
|
|
|
</aside>
|
|
</div>
|
|
|
|
<div class="row">
|
|
|
|
<div id="tail-wrapper" class="col-12 col-lg-11 col-xl-9 px-md-4">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<aside id="related-posts" aria-labelledby="related-label">
|
|
<h3 class="mb-4" id="related-label">
|
|
Further Reading
|
|
</h3>
|
|
<nav class="row row-cols-1 row-cols-md-2 row-cols-xl-3 g-4 mb-4">
|
|
|
|
<article class="col">
|
|
<a href="/post/2024-09-05-resetrestart/" class="post-preview card h-100">
|
|
<div class="card-body">
|
|
|
|
|
|
|
|
|
|
<time
|
|
|
|
data-ts="1725494400"
|
|
data-df="ll"
|
|
|
|
>
|
|
%b %e, %Y
|
|
</time>
|
|
<h4 class="pt-0 my-2">Reset and Restart</h4>
|
|
<div class="text-muted">
|
|
<p>It&rsquo;s time to reset the website and start building my blog again. I have had this domain for a number of years and it has always been used for my E-Mail. But the website has been more of a play …</p>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</article>
|
|
|
|
</nav>
|
|
</aside>
|
|
|
|
|
|
<nav class="post-navigation d-flex justify-content-between" aria-label="Post Navigation">
|
|
|
|
|
|
|
|
|
|
<a
|
|
href="/post/2024-09-05-resetrestart/"
|
|
class="btn btn-outline-primary"
|
|
aria-label="Older"
|
|
>
|
|
<p>Reset and Restart</p>
|
|
</a>
|
|
|
|
|
|
|
|
<div class="btn btn-outline-primary disabled" aria-label="Newer">
|
|
<p>-</p>
|
|
</div>
|
|
|
|
</nav>
|
|
|
|
|
|
|
|
|
|
|
|
<footer
|
|
aria-label="Site Info"
|
|
class="
|
|
d-flex flex-column justify-content-center text-muted
|
|
flex-lg-row justify-content-lg-between align-items-lg-center pb-lg-3
|
|
"
|
|
>
|
|
<p>
|
|
©
|
|
<time>2025</time>
|
|
|
|
|
|
|
|
<a href="https://comprofix.com">Comprofix</a>.
|
|
|
|
|
|
|
|
<span
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="top"
|
|
title="Except where otherwise noted, the blog posts on this site are licensed under the Creative Commons Attribution 4.0 International (CC BY 4.0) License by the author."
|
|
>Some rights reserved.</span>
|
|
</p>
|
|
|
|
<p>Using the <a
|
|
data-bs-toggle="tooltip"
|
|
data-bs-placement="top"
|
|
title="v1.0.2"
|
|
href="https://github.com/geekifan/hugo-theme-chirpy"
|
|
target="_blank"
|
|
rel="noopener"
|
|
>Chirpy</a> theme for <a href="https://gohugo.io/" target="_blank" rel="noopener">Hugo</a>.
|
|
</p>
|
|
</footer>
|
|
</div>
|
|
</div>
|
|
<div id="search-result-wrapper" class="d-flex justify-content-center d-none">
|
|
<div class="col-11 content">
|
|
<div id="search-hints">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<section>
|
|
<h2 class="panel-heading">Trending Tags</h2>
|
|
<div class="d-flex flex-wrap mt-3 mb-1 me-3">
|
|
|
|
|
|
<a class="post-tag btn btn-outline-primary" href="http://localhost:1313/tags/cd/">cd</a>
|
|
|
|
|
|
<a class="post-tag btn btn-outline-primary" href="http://localhost:1313/tags/ci/">ci</a>
|
|
|
|
|
|
<a class="post-tag btn btn-outline-primary" href="http://localhost:1313/tags/continuous-deployment/">continuous deployment</a>
|
|
|
|
|
|
<a class="post-tag btn btn-outline-primary" href="http://localhost:1313/tags/continuous-integration/">continuous integration</a>
|
|
|
|
|
|
<a class="post-tag btn btn-outline-primary" href="http://localhost:1313/tags/docker/">docker</a>
|
|
|
|
|
|
<a class="post-tag btn btn-outline-primary" href="http://localhost:1313/tags/git/">git</a>
|
|
|
|
|
|
<a class="post-tag btn btn-outline-primary" href="http://localhost:1313/tags/homelab/">homelab</a>
|
|
|
|
</div>
|
|
</section>
|
|
|
|
</div>
|
|
<div id="search-results" class="d-flex flex-wrap justify-content-center text-muted mt-3"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const DEFAULT_CONFIG = {
|
|
search: {
|
|
minChars: 1,
|
|
maxResults: 5,
|
|
fields: {
|
|
title: true,
|
|
description: true,
|
|
section: true,
|
|
contents: true
|
|
},
|
|
|
|
strictMode: true
|
|
}
|
|
};
|
|
|
|
class FastSearch {
|
|
constructor({
|
|
searchInput, resultsContainer, json,
|
|
searchResultTemplate = null,
|
|
noResultsText = null,
|
|
}) {
|
|
this.searchInput = searchInput;
|
|
this.resultsContainer = resultsContainer;
|
|
this.json = json;
|
|
this.searchResultTemplate = searchResultTemplate;
|
|
this.noResultsText = noResultsText;
|
|
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
this.loadSearchIndex();
|
|
this.searchInput.addEventListener('input', (event) => {
|
|
if (!this.searchIndex) {
|
|
this.resultsContainer.innerHTML = '<li class="search-message">Loading search index...</li>';
|
|
return;
|
|
}
|
|
this.performSearch(this.searchInput.value);
|
|
});
|
|
}
|
|
|
|
|
|
async loadSearchIndex() {
|
|
try {
|
|
const response = await fetch(this.json);
|
|
if (!response.ok) throw new Error('Failed to load search index');
|
|
const data = await response.json();
|
|
|
|
this.searchIndex = data.map(item => ({
|
|
...item,
|
|
|
|
searchableTitle: item.title?.toLowerCase() || '',
|
|
searchableDesc: item.desc?.toLowerCase() || '',
|
|
searchableSection: item.section?.toLowerCase() || '',
|
|
searchableContents: item.contents?.toLowerCase() || ''
|
|
}));
|
|
} catch (error) {
|
|
console.error('Error loading search index:', error);
|
|
this.resultsContainer.innerHTML = '<li class="search-message">Error loading search index...</li>';
|
|
}
|
|
}
|
|
|
|
escapeHtml(unsafe) {
|
|
if (!unsafe) return '';
|
|
return unsafe
|
|
.replace(/&/g, "&")
|
|
.replace(/</g, "<")
|
|
.replace(/>/g, ">")
|
|
.replace(/"/g, """)
|
|
.replace(/'/g, "'");
|
|
}
|
|
|
|
|
|
containsTerm(text, term) {
|
|
if (!text || !term) return false;
|
|
return text.includes(term);
|
|
}
|
|
|
|
performSearch(query) {
|
|
|
|
query = query.toLowerCase().trim();
|
|
|
|
|
|
if (!query || !this.searchIndex || query.length < DEFAULT_CONFIG.search.minChars) {
|
|
this.resultsContainer.innerHTML = '';
|
|
return;
|
|
}
|
|
|
|
|
|
const searchTerms = [
|
|
query,
|
|
...query.split(/\s+/).filter(term => term.length > 0)
|
|
];
|
|
|
|
|
|
const uniqueTerms = [...new Set(searchTerms)];
|
|
|
|
|
|
const requireFullQueryMatch = DEFAULT_CONFIG.search.strictMode;
|
|
|
|
|
|
const results = this.searchIndex
|
|
.map(item => {
|
|
|
|
const fullQueryMatched = this.checkFieldsForMatch(item, uniqueTerms[0]);
|
|
|
|
|
|
if (requireFullQueryMatch && !fullQueryMatched) {
|
|
return { item, score: 0, matched: false };
|
|
}
|
|
|
|
|
|
let score = 0;
|
|
let matchedTermsCount = 0;
|
|
let matchedInTitle = false;
|
|
|
|
|
|
uniqueTerms.forEach((term, index) => {
|
|
|
|
const isFullQuery = index === 0;
|
|
const matched = this.checkFieldsForMatch(item, term);
|
|
|
|
if (matched) {
|
|
matchedTermsCount++;
|
|
|
|
|
|
if (matched.inTitle) {
|
|
score += isFullQuery ? 10 : 5;
|
|
matchedInTitle = true;
|
|
}
|
|
if (matched.inDesc) {
|
|
score += isFullQuery ? 8 : 4;
|
|
}
|
|
if (matched.inSection) {
|
|
score += isFullQuery ? 6 : 3;
|
|
}
|
|
if (matched.inContents) {
|
|
score += isFullQuery ? 4 : 2;
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
const matchRatio = matchedTermsCount / uniqueTerms.length;
|
|
|
|
|
|
const finalScore = score * matchRatio * (matchedInTitle ? 1.5 : 1);
|
|
|
|
return {
|
|
item,
|
|
score: finalScore,
|
|
matched: fullQueryMatched
|
|
};
|
|
})
|
|
.filter(result => result.matched)
|
|
.sort((a, b) => b.score - a.score)
|
|
.slice(0, DEFAULT_CONFIG.search.maxResults)
|
|
.map(result => result.item);
|
|
|
|
|
|
if (results.length === 0) {
|
|
this.resultsContainer.innerHTML = '<p class="mt-5">Oops! No results found.</p>';
|
|
return;
|
|
}
|
|
|
|
const searchItems = results.map((item) => {
|
|
let categories = '';
|
|
let tags = '';
|
|
if (item.categories) {
|
|
categories = item.categories.join(', ');
|
|
categories = `<div class="me-sm-4"><i class="far fa-folder fa-fw"></i>${categories}</div>`;
|
|
}
|
|
if (item.tags) {
|
|
tags = item.tags.join(', ');
|
|
tags = `<div><i class="fa fa-tag fa-fw"></i>${tags}</div>`
|
|
}
|
|
return `
|
|
<article class="px-1 px-sm-2 px-lg-4 px-xl-0">
|
|
<header>
|
|
<h2><a href="${this.escapeHtml(item.permalink)}">${this.escapeHtml(item.title)}</a></h2>
|
|
<div class="post-meta d-flex flex-column flex-sm-row text-muted mt-1 mb-1">
|
|
${categories}
|
|
${tags}
|
|
</div>
|
|
</header>
|
|
<p>${this.escapeHtml(item.contents)}</p>
|
|
</article>
|
|
`;
|
|
}).join('');
|
|
|
|
this.resultsContainer.innerHTML = searchItems;
|
|
}
|
|
|
|
|
|
checkFieldsForMatch(item, term) {
|
|
const matches = {
|
|
inTitle: false,
|
|
inDesc: false,
|
|
inSection: false,
|
|
inContents: false
|
|
};
|
|
|
|
|
|
if (DEFAULT_CONFIG.search.fields.title && this.containsTerm(item.searchableTitle, term)) {
|
|
matches.inTitle = true;
|
|
}
|
|
|
|
if (DEFAULT_CONFIG.search.fields.description && this.containsTerm(item.searchableDesc, term)) {
|
|
matches.inDesc = true;
|
|
}
|
|
|
|
if (DEFAULT_CONFIG.search.fields.section && this.containsTerm(item.searchableSection, term)) {
|
|
matches.inSection = true;
|
|
}
|
|
|
|
if (DEFAULT_CONFIG.search.fields.contents && this.containsTerm(item.searchableContents, term)) {
|
|
matches.inContents = true;
|
|
}
|
|
|
|
|
|
if (matches.inTitle || matches.inDesc || matches.inSection || matches.inContents) {
|
|
return matches;
|
|
}
|
|
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
const search = new FastSearch({
|
|
searchInput: document.getElementById('search-input'),
|
|
resultsContainer: document.getElementById('search-results'),
|
|
json: `\/index.json`
|
|
});
|
|
|
|
</script>
|
|
</div>
|
|
|
|
<aside aria-label="Scroll to Top">
|
|
<button id="back-to-top" type="button" class="btn btn-lg btn-box-shadow">
|
|
<i class="fas fa-angle-up"></i>
|
|
</button>
|
|
</aside>
|
|
</div>
|
|
|
|
<div id="mask" class="d-none position-fixed w-100 h-100 z-1"></div>
|
|
</body>
|
|
</html> |