feat: Adds ci workflow.
Some checks failed
CI / release (push) Failing after 3m0s

This commit is contained in:
2025-04-03 11:57:22 -04:00
parent 4d099909b6
commit 5ea3e3bd86
9 changed files with 124 additions and 29 deletions

52
.gitea/workflows/ci.yaml Normal file
View File

@@ -0,0 +1,52 @@
name: CI
on:
push:
branches:
- main
pull_request: {}
workflow_dispatch: {}
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup QEMU
uses: docker/setup-qemu-action@v3
- name: Setup docker buildx
uses: docker/setup-buildx-action@v3
- name: Login to Container Registery
uses: docker/login-action@v3
with:
registery: git.housh.dev
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: git.housh.dev/homelab/docs
tags: |
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semvar,pattern={{version}}
type=semvar,pattern={{major}}.{{minor}}
type=semvar,pattern={{major}}
type=sha
type=raw,value=latest
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@@ -43,6 +43,15 @@ extension Item where M == ArticleMetadata {
} }
return primaryTag return primaryTag
} }
func getDate() -> Date {
guard let date = metadata.date else { return date }
return date
}
func getUpdatedDate() -> Date? {
return metadata.updated
}
} }
// NOTE: Most of these are taken from https://github.com/loopwerk/loopwerk.io // NOTE: Most of these are taken from https://github.com/loopwerk/loopwerk.io

View File

@@ -22,6 +22,13 @@ enum SiteMetadata {
/// Represents the valid file metadata for an article. /// Represents the valid file metadata for an article.
struct ArticleMetadata: Metadata { struct ArticleMetadata: Metadata {
/// The creation date of the article.
let date: Date?
/// The updated date of the article.
let updated: Date?
/// The articles associated tags. /// The articles associated tags.
let tags: [String] let tags: [String]

View File

@@ -40,7 +40,8 @@ private func siteHeader(_ section: Section) -> Node {
div(class: "header__logo") { div(class: "header__logo") {
a(href: "/") { a(href: "/") {
div(class: "logo") { div(class: "logo") {
"docs.housh.dev" img(src: "/static/favicon-32x32.png")
span(class: "pl-2") { "docs.housh.dev" }
} }
} }
} }
@@ -50,6 +51,9 @@ private func siteHeader(_ section: Section) -> Node {
li { li {
a(class: section == .articles ? "active" : "", href: "/articles/") { "Articles" } a(class: section == .articles ? "active" : "", href: "/articles/") { "Articles" }
} }
li {
a(href: "https://uptime.housh.dev/status/housh-dev", rel: "nofollow", target: "_blank") { "Server-Monitor" }
}
li { li {
a(class: section == .about ? "active" : "", href: "/about.html") { "About" } a(class: section == .about ? "active" : "", href: "/about.html") { "About" }
} }

View File

@@ -16,7 +16,13 @@ func tagPrefix(index: Int, totalTags: Int) -> Node {
func renderArticleInfo(_ article: Item<ArticleMetadata>) -> Node { func renderArticleInfo(_ article: Item<ArticleMetadata>) -> Node {
div(class: "text-slate-400 gray-links text-sm mb-8") { div(class: "text-slate-400 gray-links text-sm mb-8") {
span(class: "border-r border-gray pr-2 mr-2") { span(class: "border-r border-gray pr-2 mr-2") {
article.date.formatted("MMMM dd, yyyy") article.getDate().formatted("MMMM dd, yyyy")
}
if let updated = article.getUpdatedDate() {
span(class: "border-r border-gray pr-2 mr-2") {
"Updated: \(updated.formatted("MMMM dd, yyyy"))"
}
} }
%.text("\(article.body.withoutHtmlTags.numberOfWords) words, posted in ") %.text("\(article.body.withoutHtmlTags.numberOfWords) words, posted in ")
@@ -94,7 +100,7 @@ func renderArticle(context: ItemRenderingContext<ArticleMetadata>) -> Node {
title: context.item.title, title: context.item.title,
extraHeader: generateHeader(.article(context.item)) extraHeader: generateHeader(.article(context.item))
) { ) {
article(class: "pt-8 font-avenir text-lg") { article(class: "pt-8") {
h1 { context.item.title } h1 { context.item.title }
div { div {
renderArticleInfo(context.item) renderArticleInfo(context.item)
@@ -104,7 +110,7 @@ func renderArticle(context: ItemRenderingContext<ArticleMetadata>) -> Node {
div(class: "border-t border-light pt-8 mt-16") { div(class: "border-t border-light pt-8 mt-16") {
div(class: "grid lg:grid-cols-2") { div(class: "grid lg:grid-cols-2") {
h2(class: "text-4xl font-extrabold mb-8") { otherArticles.title } h4(class: "text-3xl text-amber-500 font-extrabold mb-8") { otherArticles.title }
if let tag = otherArticles.tag { if let tag = otherArticles.tag {
a(href: "/articles/tag/\(tag)") { a(href: "/articles/tag/\(tag)") {
div(class: " [&:hover]:border-b border-orange px-5 flex flex-row gap-5") { div(class: " [&:hover]:border-b border-orange px-5 flex flex-row gap-5") {
@@ -133,7 +139,7 @@ func renderArticle(context: ItemRenderingContext<ArticleMetadata>) -> Node {
func renderArticleForGrid(article: Item<ArticleMetadata>) -> Node { func renderArticleForGrid(article: Item<ArticleMetadata>) -> Node {
section { section {
h2(class: "post-title text-2xl font-bold mb-2") { h3(class: "post-title text-2xl font-bold mb-2") {
a(class: "[&:hover]:border-b border-orange-400", href: article.url) { article.title } a(class: "[&:hover]:border-b border-orange-400", href: article.url) { article.title }
} }
renderArticleInfo(article) renderArticleInfo(article)

View File

@@ -1,5 +1,6 @@
--- ---
date: 2025-4-02 date: 2025-4-02
updated: 2025-4-03
author: "Michael Housh" author: "Michael Housh"
tags: network, infrastructure tags: network, infrastructure
--- ---
@@ -53,12 +54,15 @@ This is the network where all the VoIP phones are on. It is considered
This is the network where all IoT (internet of things) devices are. This is This is the network where all IoT (internet of things) devices are. This is
considered an "untrusted" network and communications with other networks are considered an "untrusted" network and communications with other networks are
minimized to what is actually needed to work. minimized to what is actually needed to work. This network is not able to
communicate with the internet, because these devices are made by so many
different companies with unknown intentions, this adds an extra layer of
security by ensuring all communications are internal to our networks.
The exception to items placed on the IoT network is "apple" specific devices, The exception to items placed on the IoT network are "apple" specific devices,
such as home-pods and apple-tv because there are network challenges with these such as home-pods and apple-tv because there are network challenges with these
devices operating properly when placed on the IoT network (which may be resolved devices operating properly when placed on the IoT network, such as airdrop and
in the future). screen casting (which may be resolved in the future).
## Firewall ## Firewall
@@ -72,9 +76,9 @@ from communicating with other networks or the internet.
## DNS ## DNS
DNS is what translates IP addresses to domain names (i.e. `po.housh.dev` -> DNS is what translates IP addresses to domain names (i.e.
`192.168.50.6`). This is managed by the unifi management console and is accessed `po.housh.dev -> 192.168.50.6`). This is managed by the unifi management console
via `Settings -> Routing -> DNS`. and is accessed via `Settings -> Routing -> DNS`.
We primarily use wildcard records, which allow the actual routing to be handled We primarily use wildcard records, which allow the actual routing to be handled
by the servers to the correct service. by the servers to the correct service.

View File

@@ -33,6 +33,14 @@
--green: #a6e3a1; --green: #a6e3a1;
} }
/* Reset */
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
/* HEADER */ /* HEADER */
.header { .header {
display: flex; display: flex;
@@ -92,6 +100,8 @@
padding: 10px; padding: 10px;
} }
/* Nav */
nav a:hover { nav a:hover {
@apply border-b-2 border-orange-400; @apply border-b-2 border-orange-400;
} }
@@ -99,16 +109,18 @@ nav a.active {
@apply border-b-2 border-orange-400; @apply border-b-2 border-orange-400;
} }
/* Body */
body { body {
@apply bg-slate-900 font-avenir; @apply bg-slate-900 font-avenir text-xl;
} }
h1 { h1 {
@apply text-4xl; @apply text-6xl pb-2;
} }
h2 { h2 {
@apply text-3xl mb-4 pt-4; @apply text-5xl mb-8 pt-4;
color: var(--green); color: var(--green);
} }
h3 { h3 {
@@ -119,26 +131,27 @@ p {
@apply mb-8; @apply mb-8;
} }
img {
padding-top: 10px;
padding-bottom: 10px;
}
article h2 { article h2 {
@apply border-b-2 border-slate-200; @apply border-b-2 border-slate-200;
} }
article { article a {
@apply font-avenir text-lg; @apply text-orange-400;
}
article a:hover {
@apply border-b border-green-400;
}
article code {
@apply bg-amber-700;
} }
.container { .container {
@apply px-10; @apply px-10;
} }
* { .container img {
-webkit-box-sizing: border-box; padding-top: 10px;
-moz-box-sizing: border-box; padding-bottom: 10px;
-ms-box-sizing: border-box;
box-sizing: border-box;
} }

File diff suppressed because one or more lines are too long

View File

@@ -9,7 +9,7 @@ https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+cli
code[class*="language-"], code[class*="language-"],
pre[class*="language-"] { pre[class*="language-"] {
color: #ccc; color: #ccc;
background: none; background: #121416;
font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
font-size: 1em; font-size: 1em;
text-align: left; text-align: left;