docker / build-push-arm64cross (push) Successful in 10s
docker / deploy-docs (push) Successful in 31s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 26m54s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 26m56s
apple / screenshots (push) Canceled after 11m30s
windows-host / package (push) Failing after 12s
windows-host / winget-source (push) Skipped
apple / swift (push) Successful in 6m2s
ci / web (push) Successful in 1m53s
ci / docs-site (push) Successful in 1m29s
ci / rust-arm64 (push) Successful in 9m56s
android / android (push) Successful in 12m33s
ci / bench (push) Successful in 7m17s
decky / build-publish (push) Successful in 29s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 12s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 12s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 11s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 11s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 19s
arch / build-publish (push) Successful in 18m18s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 16s
deb / build-publish (push) Successful in 9m2s
ci / rust (push) Failing after 19m38s
deb / build-publish-client-arm64 (push) Successful in 7m21s
deb / build-publish-host (push) Successful in 9m43s
`winget install unom.PunktfunkHost` after adding the source, and `winget upgrade`
from then on. Windows had no update path at all before this — no self-update, no
package manager — so keeping a host current meant noticing a release and
re-running an installer by hand.
Ships the manifest trio in winget-pkgs' own format (so submitting upstream later
is a copy, not a rewrite) plus a release-time generator that substitutes only
version, URL, hash and release-notes link. Everything reviewable — the silent
switches, the agreements, the installation notes — stays in the checked-in
templates rather than buried in a generator.
Silent installs deliberately take the SAME task defaults the wizard shows: a
per-channel default is a support trap. The disclosures the wizard puts on screen
travel as manifest Agreements instead, shown before install and requiring
acceptance — VB-Audio's bundling grant wants the user to see VB-CABLE's origin
and donationware status, and a silent install shows them nothing otherwise. The
console password can only be pointed at, never printed: it is generated per
install and the notes are fixed at publish time.
Self-hosted rather than the community repo, which gates on Defender/SmartScreen
validation the self-signed installer cert would not clear today. The source is
three endpoints — /information, /manifestSearch, /packageManifests/{id}. The
reference implementation's other twenty are its admin API for mutating a
CosmosDB; a catalogue generated at release time has nothing to mutate.
It runs on unom-1 as a stock bun image with the two .mjs files bind-mounted, the
same shape as the flatpak server, so there is no image to build or pull. The
catalogue is derived from the RELEASES rather than local files: winget resolves
--version and upgrade against the version list, so a source that only knew the
newest release could neither pin an older one nor show an upgrade path from it.
That also leaves no state to drift — re-running the build reproduces it exactly.
NormalizedPackageNameAndPublisher is declared unsupported on purpose. winget
derives it client-side with its own normalization, and a near-miss silently
mis-correlates an installed host; ProductCode is exact and Inno gives us one.
28 checks drive the handler directly, and CI gates on them before anything
reaches the box — a wrong response shape does not fail loudly, it just makes
winget report "no package found".
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
140 lines
6.4 KiB
YAML
140 lines
6.4 KiB
YAML
# Deploy-only: bring up the two unom-1 pieces that live in THIS repo but whose normal
|
|
# deploys are coupled to heavy build workflows — docs to docker.yml's 5-image matrix,
|
|
# the flatpak server to flatpak.yml's full flatpak-builder run. This workflow does
|
|
# NEITHER build: it just (re)places the compose files and pulls the already-published
|
|
# images, so unom/infra's deploy-all can bring a fresh unom-1 fully up in a single
|
|
# dispatch without triggering those rebuilds.
|
|
#
|
|
# docs -> pulls git.unom.io/unom/punktfunk-docs:latest (built by docker.yml) and
|
|
# brings it up on :3220.
|
|
# flatpak -> brings up the caddy:2-alpine static server on :3230. The OSTree repo
|
|
# CONTENT (./site) is NOT shipped here — it is regenerated by flatpak.yml
|
|
# on the next client build, or restored from the unom-1 backup
|
|
# (unom/infra scripts/restore-unom-1.sh, `files` tag). A fresh box serves
|
|
# an empty repo until then; that is expected.
|
|
#
|
|
# Dispatched by unom/infra scripts/deploy-all.sh: `dispatch-and-wait.sh punktfunk
|
|
# deploy-services.yml`. Uses the same secret set docker.yml/flatpak.yml already rely on:
|
|
# DEPLOY_HOST/USER/PORT/SSH_KEY (the unom-ci-deploy key) + REGISTRY_TOKEN (docs pull).
|
|
name: deploy-services
|
|
run-name: ${{ gitea.actor }} deploy docs + flatpak server
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
deploy_host:
|
|
description: "Box IP to deploy to; deploy-all passes the freshly-provisioned target IP. Blank (push) uses the DEPLOY_HOST secret."
|
|
required: false
|
|
|
|
jobs:
|
|
docs:
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 10
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Sync compose file
|
|
# SHA-pinned (receives DEPLOY_SSH_KEY): a moved tag would mean credential
|
|
# exfiltration. v0.1.7 = 917f8b8. Bump the SHA + trailing version together.
|
|
uses: appleboy/scp-action@917f8b81dfc1ccd331fef9e2d61bdc6c8be94634 # v0.1.7
|
|
with:
|
|
host: ${{ inputs.deploy_host || secrets.DEPLOY_HOST }}
|
|
username: ${{ secrets.DEPLOY_USER }}
|
|
port: ${{ secrets.DEPLOY_PORT }}
|
|
key: ${{ secrets.DEPLOY_SSH_KEY }}
|
|
source: "compose.production.yml"
|
|
target: "~/punktfunk-docs"
|
|
overwrite: true
|
|
|
|
- name: Pull and start docs
|
|
# SHA-pinned: receives DEPLOY_SSH_KEY + REGISTRY_TOKEN. v1.2.5 = 0ff4204.
|
|
uses: appleboy/ssh-action@0ff4204d59e8e51228ff73bce53f80d53301dee2 # v1.2.5
|
|
env:
|
|
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
|
with:
|
|
host: ${{ inputs.deploy_host || secrets.DEPLOY_HOST }}
|
|
username: ${{ secrets.DEPLOY_USER }}
|
|
port: ${{ secrets.DEPLOY_PORT }}
|
|
key: ${{ secrets.DEPLOY_SSH_KEY }}
|
|
# Token enters via env, never the script text (keeps it out of run logs).
|
|
envs: REGISTRY_TOKEN
|
|
script: |
|
|
set -euo pipefail
|
|
printf '%s' "$REGISTRY_TOKEN" | docker login git.unom.io -u enricobuehler --password-stdin
|
|
cd ~/punktfunk-docs
|
|
docker compose -f compose.production.yml pull docs
|
|
docker compose -f compose.production.yml up -d --no-build docs
|
|
|
|
flatpak:
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 10
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Sync flatpak server compose + Caddyfile
|
|
uses: appleboy/scp-action@917f8b81dfc1ccd331fef9e2d61bdc6c8be94634 # v0.1.7
|
|
with:
|
|
host: ${{ inputs.deploy_host || secrets.DEPLOY_HOST }}
|
|
username: ${{ secrets.DEPLOY_USER }}
|
|
port: ${{ secrets.DEPLOY_PORT }}
|
|
key: ${{ secrets.DEPLOY_SSH_KEY }}
|
|
# Land both files flat in ~/unom-flatpak/ (drop the packaging/flatpak/server/ prefix).
|
|
source: "packaging/flatpak/server/compose.production.yml,packaging/flatpak/server/Caddyfile"
|
|
target: "~/unom-flatpak"
|
|
strip_components: 3
|
|
overwrite: true
|
|
|
|
- name: Start flatpak static server
|
|
uses: appleboy/ssh-action@0ff4204d59e8e51228ff73bce53f80d53301dee2 # v1.2.5
|
|
with:
|
|
host: ${{ inputs.deploy_host || secrets.DEPLOY_HOST }}
|
|
username: ${{ secrets.DEPLOY_USER }}
|
|
port: ${{ secrets.DEPLOY_PORT }}
|
|
key: ${{ secrets.DEPLOY_SSH_KEY }}
|
|
script: |
|
|
set -euo pipefail
|
|
# ./site (the OSTree repo) is NOT shipped by this workflow. Ensure the
|
|
# bind-mount source exists so caddy starts; content is restored from the
|
|
# unom-1 backup or regenerated by flatpak.yml's next publish.
|
|
mkdir -p ~/unom-flatpak/site/repo
|
|
cd ~/unom-flatpak
|
|
docker compose -f compose.production.yml up -d
|
|
|
|
winget:
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 10
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Sync winget source compose + server
|
|
uses: appleboy/scp-action@917f8b81dfc1ccd331fef9e2d61bdc6c8be94634 # v0.1.7
|
|
with:
|
|
host: ${{ inputs.deploy_host || secrets.DEPLOY_HOST }}
|
|
username: ${{ secrets.DEPLOY_USER }}
|
|
port: ${{ secrets.DEPLOY_PORT }}
|
|
key: ${{ secrets.DEPLOY_SSH_KEY }}
|
|
# Land all three flat in ~/unom-winget/ (drop the packaging/winget/server/ prefix).
|
|
source: "packaging/winget/server/compose.production.yml,packaging/winget/server/server.mjs,packaging/winget/server/handler.mjs"
|
|
target: "~/unom-winget"
|
|
strip_components: 3
|
|
overwrite: true
|
|
|
|
- name: Start winget REST source
|
|
uses: appleboy/ssh-action@0ff4204d59e8e51228ff73bce53f80d53301dee2 # v1.2.5
|
|
with:
|
|
host: ${{ inputs.deploy_host || secrets.DEPLOY_HOST }}
|
|
username: ${{ secrets.DEPLOY_USER }}
|
|
port: ${{ secrets.DEPLOY_PORT }}
|
|
key: ${{ secrets.DEPLOY_SSH_KEY }}
|
|
script: |
|
|
set -euo pipefail
|
|
# ./data/data.json is NOT shipped by this workflow — windows-host.yml rsyncs it on each
|
|
# stable tag (same content/config split as the flatpak repo). Ensure the bind-mount
|
|
# source exists so the container starts; it serves 503 until the first catalogue lands.
|
|
mkdir -p ~/unom-winget/data
|
|
cd ~/unom-winget
|
|
docker compose -f compose.production.yml up -d
|
|
# Surface a missing catalogue here rather than letting winget report "no package found".
|
|
sleep 3
|
|
curl -fsS http://127.0.0.1:3240/healthz || echo "NOTE: no catalogue yet - publish a stable tag to populate it"
|