Add CI and release workflows
CI / test (push) Successful in 28s

This commit is contained in:
Veillax committed 2026-10-27 18:06:42 -06:00
1 parent 69933f37e5
commit ea1a0c85a9
4 files changed
+134

No files matched your search

+25
View File
@@ -0,0 +1,25 @@
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Test
run: npm test
# The app is static files, so a broken manifest or service worker only shows up on a phone.
- name: Manifest and scripts parse
run: |
node -e "JSON.parse(require('fs').readFileSync('public/manifest.webmanifest','utf8'))"
for f in public/*.js; do node --check "$f"; done
+37
View File
@@ -0,0 +1,37 @@
name: Release
# Push a tag such as v0.2.0 to publish public/ as a release archive that can be
# unpacked into SANDBAR_APP_DIR or hosted on any static site:
# git tag -a v0.2.0 -m "remora v0.2.0" && git push origin v0.2.0
on:
push:
tags: ['v*']
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # release notes come from the history since the previous tag
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Test
run: npm test
- name: Build release archive
run: |
mkdir -p dist
tar -C public -czf "dist/remora_${GITHUB_REF_NAME}.tar.gz" .
(cd public && zip -qr "../dist/remora_${GITHUB_REF_NAME}.zip" .)
(cd dist && sha256sum remora_* > SHA256SUMS)
# Optional secret RELEASE_TOKEN: an access token that can write releases, for
# servers where the automatic job token can't.
- name: Publish the release
env:
TOKEN: ${{ secrets.RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
run: sh deploy/publish-release.sh "${GITHUB_REF_NAME}"
+1
View File
@@ -1,2 +1,3 @@
node_modules/
.env
dist/
+71
View File
@@ -0,0 +1,71 @@
#!/bin/sh
# Creates (or updates) the Gitea release for a tag and uploads what the release job packed.
#
# TOKEN=<access token that can write releases> deploy/publish-release.sh v0.2.0
#
# In Gitea Actions GITHUB_SERVER_URL and GITHUB_REPOSITORY are already set. Safe to
# re-run: an existing release is reused and assets with the same name are replaced.
set -eu
TAG=${1:?usage: publish-release.sh <tag>}
: "${TOKEN:?set TOKEN to a Gitea access token that can write releases}"
SERVER=${GITHUB_SERVER_URL:-${GITEA_SERVER_URL:-https://git.veillax.com}}
REPO=${GITHUB_REPOSITORY:-Veillax/remora}
API="$SERVER/api/v1/repos/$REPO"
AUTH="Authorization: token $TOKEN"
# a JSON helper without needing jq: any python will do
PY=python3
python3 -c 'pass' > /dev/null 2>&1 || PY=python
json() { "$PY" -c "$1"; }
# release notes: the commit subjects since the previous tag
prev=$(git describe --tags --abbrev=0 "$TAG^" 2>/dev/null || true)
if [ -n "$prev" ]; then
notes=$(git log --pretty='format:- %s' "$prev..$TAG")
else
notes=$(git log --pretty='format:- %s' "$TAG")
fi
prerelease=false
case "$TAG" in *-*) prerelease=true ;; esac
body=$(NOTES="$notes" TAG="$TAG" PRE="$prerelease" json '
import json, os
print(json.dumps({"tag_name": os.environ["TAG"], "name": os.environ["TAG"], "body": os.environ["NOTES"],
"draft": False, "prerelease": os.environ["PRE"] == "true"}))')
# reuse the release when a failed job is re-run
id=$(curl -fsS -H "$AUTH" "$API/releases/tags/$TAG" 2>/dev/null | json 'import sys, json; print(json.load(sys.stdin)["id"])' 2>/dev/null || true)
if [ -z "$id" ]; then
echo "creating release $TAG"
id=$(curl -fsS -X POST -H "$AUTH" -H 'Content-Type: application/json' -d "$body" "$API/releases" | json 'import sys, json; print(json.load(sys.stdin)["id"])')
else
echo "release $TAG already exists (id $id): replacing its files"
fi
# the ids of the release's assets with a given name (a failed upload can leave a partial one behind)
asset_ids() {
curl -fsS -H "$AUTH" "$API/releases/$id/assets" | "$PY" -c 'import sys, json
for a in json.load(sys.stdin):
if a["name"] == sys.argv[1]:
print(a["id"])' "$1"
}
for f in dist/*.tar.gz dist/*.zip dist/SHA256SUMS; do
[ -f "$f" ] || continue
name=$(basename "$f")
n=1
while :; do
for aid in $(asset_ids "$name"); do
curl -fsS -X DELETE -H "$AUTH" "$API/releases/$id/assets/$aid" > /dev/null
done
echo "uploading $name (attempt $n)"
if curl -fsS --max-time 1200 -X POST -H "$AUTH" -F "attachment=@$f" "$API/releases/$id/assets?name=$name" > /dev/null; then
break
fi
# large uploads can hit a proxy timeout (HTTP 502); try again
[ "$n" -lt 5 ] || { echo "giving up on $name after $n attempts" >&2; exit 1; }
n=$((n + 1))
sleep $((n * 10))
done
done
echo "published $SERVER/$REPO/releases/tag/$TAG"