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
}
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

View File

@@ -22,6 +22,13 @@ enum SiteMetadata {
/// Represents the valid file metadata for an article.
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.
let tags: [String]

View File

@@ -40,7 +40,8 @@ private func siteHeader(_ section: Section) -> Node {
div(class: "header__logo") {
a(href: "/") {
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 {
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 {
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 {
div(class: "text-slate-400 gray-links text-sm mb-8") {
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 ")
@@ -94,7 +100,7 @@ func renderArticle(context: ItemRenderingContext<ArticleMetadata>) -> Node {
title: context.item.title,
extraHeader: generateHeader(.article(context.item))
) {
article(class: "pt-8 font-avenir text-lg") {
article(class: "pt-8") {
h1 { context.item.title }
div {
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: "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 {
a(href: "/articles/tag/\(tag)") {
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 {
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 }
}
renderArticleInfo(article)

View File

@@ -1,5 +1,6 @@
---
date: 2025-4-02
updated: 2025-4-03
author: "Michael Housh"
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
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
devices operating properly when placed on the IoT network (which may be resolved
in the future).
devices operating properly when placed on the IoT network, such as airdrop and
screen casting (which may be resolved in the future).
## Firewall
@@ -72,9 +76,9 @@ from communicating with other networks or the internet.
## DNS
DNS is what translates IP addresses to domain names (i.e. `po.housh.dev` ->
`192.168.50.6`). This is managed by the unifi management console and is accessed
via `Settings -> Routing -> DNS`.
DNS is what translates IP addresses to domain names (i.e.
`po.housh.dev -> 192.168.50.6`). This is managed by the unifi management console
and is accessed via `Settings -> Routing -> DNS`.
We primarily use wildcard records, which allow the actual routing to be handled
by the servers to the correct service.

View File

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

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-"],
pre[class*="language-"] {
color: #ccc;
background: none;
background: #121416;
font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
font-size: 1em;
text-align: left;