Three things, one subject: making CI say the truth about this repo.
## The red on every run was ours, not the runners'
Every docker-build run came back success, success, failure — the same
shape for weeks. The failing job was `deploy`, and it was failing to
*not run*:
if: ${{ github.event.inputs.deploy == 'true' }}
On a push there is no github.event.inputs at all. This Forgejo does not
treat that as false and skip; it dispatches the job, the runner cannot
resolve it, and the task ends in "Early termination". The runners were
never at fault, and nothing about them needed changing.
The `'runs-on' key not defined` line is a red herring: the `build` job
prints it too and succeeds. It names the job's *needs* target, not the
job, and the old android-apk workflow used `needs:` happily for months.
Deploy is now its own workflow with only workflow_dispatch — no
condition to evaluate, so nothing can be dispatched by mistake. No job
in either file now carries a job-level `if`. The one conditional left is
a *step* (push to registry), and step conditions are evaluated by the
runner once the job is already running, which is why that one has always
worked.
## dev and main
docker-build now runs on `dev` as well. Both branches prove the same two
things — tests pass, image builds — and only `main` publishes the image,
so nothing on `dev` can be mistaken for something deployable. Deploying
stays a person pressing a button after looking at the change.
CONTRIBUTING.md documents the flow.
## Android
Removed: the mobile/ Capacitor project, docs/mobile-build.md, and the
Android bits of scripts/release.sh. All of it is in git history — 4613a278
is the last commit that had it — for when it is rebuilt.
src/utils/platform.js stays. isMobileClient only decides token lifetime,
it is twelve lines, and it is the contract a future app would come back
to; deleting it would be a change to auth for no gain.
.github/workflows/ went too — all five. There is no GitHub remote on
this repository, so none of them has ever run, and two of them wrote
into mobile/ paths that no longer exist.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
103 lines
3.3 KiB
Bash
Executable file
103 lines
3.3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# ============================================================
|
|
# PedScribe release helper — one command to tag a new version.
|
|
#
|
|
# Usage:
|
|
# scripts/release.sh 6.1.1 # bump to 6.1.1
|
|
# scripts/release.sh 6.1.1 --push # also git push + tag push
|
|
#
|
|
# What it does:
|
|
# 1. Updates version in root package.json and package-lock.json (requires Node)
|
|
# 2. Commits the version bump
|
|
# 3. (optional) git push + push the new tag
|
|
#
|
|
# It does NOT:
|
|
# - Build the Docker image (run `./scripts/build-image.sh`/`docker compose up -d --no-build` yourself
|
|
# or wire it to a deploy script / CI hook)
|
|
# - Touch anything Android. The Capacitor project and its APK build were
|
|
# removed; if they come back, restore the version-bump lines from git
|
|
# history along with them.
|
|
# ============================================================
|
|
|
|
set -euo pipefail
|
|
|
|
VERSION="${1:-}"
|
|
PUSH=false
|
|
for arg in "${@:2}"; do
|
|
case "$arg" in
|
|
--push) PUSH=true ;;
|
|
esac
|
|
done
|
|
|
|
if [[ -z "$VERSION" ]]; then
|
|
echo "usage: $0 <version> [--push]"
|
|
echo " example: $0 6.1.1 --push"
|
|
exit 1
|
|
fi
|
|
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
echo "ERROR: version must be semver X.Y.Z (e.g. 6.1.1). got: $VERSION" >&2
|
|
exit 1
|
|
fi
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
cd "$ROOT"
|
|
|
|
if [[ -n "$(git status --porcelain)" ]]; then
|
|
echo "ERROR: working tree has uncommitted changes. commit or stash first." >&2
|
|
git status --short >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "==> Bumping to v$VERSION"
|
|
|
|
# Parse every manifest before writing; change metadata only, never resolve dependencies.
|
|
# Replace the lock atomically so its two version fields cannot be partially updated.
|
|
node - "$VERSION" <<'NODE'
|
|
const fs = require('node:fs');
|
|
const version = process.argv[2];
|
|
const files = ['package.json', 'package-lock.json'];
|
|
const updates = files.map(file => [file, JSON.parse(fs.readFileSync(file, 'utf8'))]);
|
|
for (const [file, data] of updates) {
|
|
data.version = version;
|
|
if (file === 'package-lock.json') data.packages[''].version = version;
|
|
}
|
|
for (const [file, data] of updates) {
|
|
fs.writeFileSync(file + '.tmp', JSON.stringify(data, null, 2) + '\n');
|
|
fs.renameSync(file + '.tmp', file);
|
|
}
|
|
NODE
|
|
echo " updated package.json and package-lock.json"
|
|
|
|
|
|
# Commit
|
|
git add package.json package-lock.json
|
|
git commit -m "Release v${VERSION}"
|
|
echo " committed"
|
|
|
|
# Tag
|
|
git tag -a "v${VERSION}" -m "Release v${VERSION}"
|
|
echo " tagged v${VERSION}"
|
|
|
|
if $PUSH; then
|
|
# This repo's remote is "forgejo", not "origin". Prefer forgejo, fall back
|
|
# to origin, otherwise use the only remote there is — so this keeps working
|
|
# if the remote is ever renamed. Pushing the tag is what makes CI attach the
|
|
# signed APK to a Forgejo release for Obtainium; the branch push alone only
|
|
# builds it as a 30-day workflow artifact.
|
|
REMOTE=""
|
|
for candidate in forgejo origin; do
|
|
if git remote get-url "$candidate" >/dev/null 2>&1; then REMOTE="$candidate"; break; fi
|
|
done
|
|
if [[ -z "$REMOTE" ]]; then
|
|
REMOTE=$(git remote | head -1)
|
|
fi
|
|
if [[ -z "$REMOTE" ]]; then
|
|
echo "ERROR: no git remote configured — cannot push. Commit and tag are still local." >&2
|
|
exit 1
|
|
fi
|
|
git push "$REMOTE" HEAD
|
|
git push "$REMOTE" "v${VERSION}"
|
|
echo " pushed to $REMOTE"
|
|
fi
|
|
|
|
echo "==> Done. v$VERSION."
|