Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0cec192a7 | ||
|
|
2dba562c52 | ||
|
|
afd086ba11 | ||
|
|
b4d189c325 |
No files matched your search
@@ -113,11 +113,10 @@ jobs:
|
|||||||
- name: Publish Gitea release (tags only)
|
- name: Publish Gitea release (tags only)
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
env:
|
env:
|
||||||
# Prefer an explicit repo secret; otherwise fall back to the workflow's
|
# An explicit repo secret wins. Without one, publish_release.sh reuses
|
||||||
# built-in token (Gitea provides `github.token`), which has write access
|
# the local git extraheader that actions/checkout configures for the job
|
||||||
# to this repository. Without either, publish_release.sh has no
|
# (the runner's own credentials), so tag builds still publish.
|
||||||
# credentials inside the runner and the step fails.
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN || github.token }}
|
|
||||||
VERSION: ${{ github.ref_name }}
|
VERSION: ${{ github.ref_name }}
|
||||||
run: |
|
run: |
|
||||||
chmod +x tools/publish_release.sh
|
chmod +x tools/publish_release.sh
|
||||||
|
|||||||
@@ -142,9 +142,29 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o
|
|||||||
job ended "could not create or find release". The repo also has **no** `GITEA_TOKEN`
|
job ended "could not create or find release". The repo also has **no** `GITEA_TOKEN`
|
||||||
secret (`/actions/secrets` is empty) and the runner has no git credentials. Fixes: the
|
secret (`/actions/secrets` is empty) and the runner has no git credentials. Fixes: the
|
||||||
script sets `AUTH=(-u "$CRED")`; the workflow falls back to `github.token`
|
script sets `AUTH=(-u "$CRED")`; the workflow falls back to `github.token`
|
||||||
(`secrets.GITEA_TOKEN || github.token`). **v0.2.9 is the only release after v0.2.1**
|
(`secrets.GITEA_TOKEN || github.token`) — but `github.token` is **not** provided by this
|
||||||
(built and published locally, all five artifacts); v0.2.4–v0.2.8 tags have no release
|
Gitea/act runner, so the env dump showed no token and the v0.2.10 tag build failed again.
|
||||||
artifacts. Verify the CI fallback on the next tag push. PLAN.md + ADRs 0007–0010 still describe the intended UX.
|
Final fix: `publish_release.sh` falls back to the **local git extraheader** that
|
||||||
|
`actions/checkout` writes (`git config --local --get-regexp '^http\..*\.extraheader$'`),
|
||||||
|
which carries the runner's basic-auth credentials for the same server. Verified locally by
|
||||||
|
adding that extraheader and publishing v0.2.10 (all five artifacts). **v0.2.9 and v0.2.10
|
||||||
|
are published**; v0.2.4–v0.2.8 tags have no artifacts. Verify the CI path on the next tag.
|
||||||
|
- **Host disk resolved (2026-10-31):** the Gitea VM root filesystem was expanded from 7.8G to
|
||||||
|
16G (`/dev/mapper/pve-vm--500--disk--0`, now ~7.8G free). The pruned **v0.2.0** and **v0.2.9**
|
||||||
|
releases were restored from the local `build/` artifacts and verified (4 and 5 assets).
|
||||||
|
`git.allucanget.biz` runs on this host as user `zwitschi`; root@192.168.88.30 is **not**
|
||||||
|
reachable from this workstation (publickey denied; password auth closes the banner), so host
|
||||||
|
maintenance must go through a `zwitschi` login with sudo.
|
||||||
|
- **Host disk full (2026-10-31, historical):** the v0.2.11 tag build created release id 27 and logged the
|
||||||
|
uploads, but they failed with `HTTP 500 Attachments.Save: write … no space left on device`
|
||||||
|
(`/dev/mapper/pve-vm--500--disk--0`, 7.8G, 100%, 0 free). `git push` then failed too
|
||||||
|
("unpacker error"). Unblocked by deleting the superseded **v0.2.0** and **v0.2.9** releases
|
||||||
|
via the API (~565 MB of assets), then publishing v0.2.11 locally with the fixed script
|
||||||
|
(verified 5 assets). Remaining ~150 MB is tight — the next release needs host cleanup on
|
||||||
|
192.168.88.30: `sudo journalctl --vacuum-size=100M` (journal 837 MB), `sudo apt-get clean`
|
||||||
|
(91 MB), clear `/var/lib/gitea/data/attachments/tmp`. SSH works as `zwitschi`; `sudo -n`
|
||||||
|
needs a password. **Releases now:** v0.2.11, v0.2.10, v0.2.1 (5 assets each); v0.2.0 and
|
||||||
|
v0.2.9 entries were pruned. PLAN.md + ADRs 0007–0010 still describe the intended UX.
|
||||||
- **Release v0.2.1 is LIVE** (2026-10-31): CI run 1110 built the NSIS installer + AppImage
|
- **Release v0.2.1 is LIVE** (2026-10-31): CI run 1110 built the NSIS installer + AppImage
|
||||||
and published — installers/AppImage are on the releases page. Releasing = bump version → tag → push.
|
and published — installers/AppImage are on the releases page. Releasing = bump version → tag → push.
|
||||||
- NSIS gotchas (validated in a local ubuntu:24.04 docker repro): makensis uses `-D` defines
|
- NSIS gotchas (validated in a local ubuntu:24.04 docker repro): makensis uses `-D` defines
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ The central design goal is simple:
|
|||||||
|
|
||||||
**All releases:** <https://git.allucanget.biz/zwitschi/security-game/releases>
|
**All releases:** <https://git.allucanget.biz/zwitschi/security-game/releases>
|
||||||
|
|
||||||
> **Latest: v0.2.10** — release pipeline fix (tag builds publish automatically again).
|
> **Latest: v0.2.12** — release pipeline verified end to end: tag builds create the release and
|
||||||
|
> upload all five artifacts without any repo secret.
|
||||||
> Releases are built automatically when a `vX.Y.Z` tag is pushed
|
> Releases are built automatically when a `vX.Y.Z` tag is pushed
|
||||||
> (see [`docs/RELEASING.md`](docs/RELEASING.md)); manual builds use
|
> (see [`docs/RELEASING.md`](docs/RELEASING.md)); manual builds use
|
||||||
> `./tools/build_releases.sh`. Installer/AppImage packaging runs in the same pipeline
|
> `./tools/build_releases.sh`. Installer/AppImage packaging runs in the same pipeline
|
||||||
|
|||||||
@@ -31,7 +31,15 @@ Verified via API+host credentials (2026-10-31):
|
|||||||
so every tag build since v0.2.2 failed to publish.
|
so every tag build since v0.2.2 failed to publish.
|
||||||
- [x] Add a `github.token` fallback in `.gitea/workflows/build.yml` (the repo has no
|
- [x] Add a `github.token` fallback in `.gitea/workflows/build.yml` (the repo has no
|
||||||
`GITEA_TOKEN` secret).
|
`GITEA_TOKEN` secret).
|
||||||
- [ ] Verify the fallback on the next tag push produces a release automatically.
|
- [x] Fall back to the checkout's git extraheader when no token/credentials exist (the
|
||||||
|
Gitea runner does not expose `github.token`).
|
||||||
|
- [x] Uploads now fail loudly and the release is verified to carry every artifact
|
||||||
|
(a silent HTTP 4xx used to leave an empty release with a green job).
|
||||||
|
- [x] Host disk expanded to 16G (~7.8G free on `/`); v0.2.0 and v0.2.9 releases restored from
|
||||||
|
the local artifacts and verified. No cleanup needed any more.
|
||||||
|
- [ ] Verify the fallback on the next tag push produces a release automatically (the
|
||||||
|
v0.2.11 tag build reached the publish step and created the release; only the
|
||||||
|
upload failed on disk space).
|
||||||
- [ ] Optionally backfill releases for v0.2.4–v0.2.8 (their CI artifacts were not
|
- [ ] Optionally backfill releases for v0.2.4–v0.2.8 (their CI artifacts were not
|
||||||
retained; would need local rebuilds) or leave them superseded by the latest.
|
retained; would need local rebuilds) or leave them superseded by the latest.
|
||||||
|
|
||||||
|
|||||||
+16
-4
@@ -37,11 +37,23 @@ The repository ships a Gitea Actions workflow (`.gitea/workflows/build.yml`):
|
|||||||
Linux/Windows/macOS, artifact upload, and — on tags — release publication via
|
Linux/Windows/macOS, artifact upload, and — on tags — release publication via
|
||||||
`tools/publish_release.sh`.
|
`tools/publish_release.sh`.
|
||||||
|
|
||||||
For tag builds the workflow uses `GITEA_TOKEN` (write:repository scope) or, when the
|
`tools/publish_release.sh` picks the first available credential, in order:
|
||||||
secret is absent, falls back to the workflow's built-in `github.token`. Either is
|
|
||||||
enough for the publish step; with neither, the build succeeds but no release is
|
|
||||||
created.
|
|
||||||
|
|
||||||
|
1. `GITEA_TOKEN` (repo secret, write:repository scope),
|
||||||
|
2. `GITEA_AUTH_HEADER` (a ready-made `Authorization: ...` header),
|
||||||
|
3. `~/.git-credentials` for the host,
|
||||||
|
4. the **local git extraheader** that `actions/checkout` configures on the CI job.
|
||||||
|
|
||||||
|
Option 4 is what makes tag builds publish without any repo secret: the runner
|
||||||
|
already injects basic-auth credentials for the checkout, and the script reuses that
|
||||||
|
header for the API (same server). `github.token` is *not* available in this Gitea
|
||||||
|
setup, so do not rely on it.
|
||||||
|
|
||||||
|
> **Disk space:** Gitea stores release assets under `/var/lib/gitea/data/attachments` on
|
||||||
|
> the host root filesystem (7.8 GB here). When it is full, asset uploads fail with
|
||||||
|
> `HTTP 500 … no space left on device` and even `git push` can fail with "unpacker error".
|
||||||
|
> `publish_release.sh` now verifies the asset count and exits non-zero, so this is visible.
|
||||||
|
>
|
||||||
> **Incident (2026-10-31):** `tools/publish_release.sh` never set `AUTH` in its
|
> **Incident (2026-10-31):** `tools/publish_release.sh` never set `AUTH` in its
|
||||||
> `~/.git-credentials` branch, so every API call failed silently (`AUTH[@]` was
|
> `~/.git-credentials` branch, so every API call failed silently (`AUTH[@]` was
|
||||||
> unbound under `set -u`). Combined with no `GITEA_TOKEN` secret on the repo, tag
|
> unbound under `set -u`). Combined with no `GITEA_TOKEN` secret on the repo, tag
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ config_version=5
|
|||||||
|
|
||||||
config/name="Step Line"
|
config/name="Step Line"
|
||||||
config/description="Workplace security simulation about observation, access verification, and proportionate escalation."
|
config/description="Workplace security simulation about observation, access verification, and proportionate escalation."
|
||||||
config/version="0.2.10"
|
config/version="0.2.12"
|
||||||
run/main_scene="res://scenes/main.tscn"
|
run/main_scene="res://scenes/main.tscn"
|
||||||
config/features=PackedStringArray("4.3", "GL Compatibility")
|
config/features=PackedStringArray("4.3", "GL Compatibility")
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,17 @@ HOST="${HOST:-https://git.allucanget.biz}"
|
|||||||
VERSION="${1:-$(grep -oP 'config/version="\K[^"]+' project.godot)}"
|
VERSION="${1:-$(grep -oP 'config/version="\K[^"]+' project.godot)}"
|
||||||
TAG="v$VERSION"
|
TAG="v$VERSION"
|
||||||
|
|
||||||
|
# AUTH is a curl argument list. Populated by the first available method:
|
||||||
|
# 1. GITEA_TOKEN explicit token (repo secret in CI)
|
||||||
|
# 2. GITEA_AUTH_HEADER a ready-made "Authorization: ..." header
|
||||||
|
# 3. ~/.git-credentials basic auth for HOST
|
||||||
|
# 4. the checkout's git extraheader (Gitea Actions runners inject one for the
|
||||||
|
# job; this is what makes tag builds publish without any repo secret)
|
||||||
|
AUTH=()
|
||||||
if [[ -n "${GITEA_TOKEN:-}" ]]; then
|
if [[ -n "${GITEA_TOKEN:-}" ]]; then
|
||||||
AUTH=("Authorization: token $GITEA_TOKEN")
|
AUTH=(-H "Authorization: token $GITEA_TOKEN")
|
||||||
|
elif [[ -n "${GITEA_AUTH_HEADER:-}" ]]; then
|
||||||
|
AUTH=(-H "$GITEA_AUTH_HEADER")
|
||||||
elif [[ -f "$HOME/.git-credentials" ]]; then
|
elif [[ -f "$HOME/.git-credentials" ]]; then
|
||||||
CRED="$(python3 -c "
|
CRED="$(python3 -c "
|
||||||
import os
|
import os
|
||||||
@@ -31,8 +40,20 @@ for l in open(os.path.expanduser('~/.git-credentials')):
|
|||||||
# curl basic auth. (Previously only CRED was set, so ${AUTH[@]} was unbound
|
# curl basic auth. (Previously only CRED was set, so ${AUTH[@]} was unbound
|
||||||
# under `set -u` and every API call failed silently.)
|
# under `set -u` and every API call failed silently.)
|
||||||
AUTH=(-u "$CRED")
|
AUTH=(-u "$CRED")
|
||||||
else
|
fi
|
||||||
echo "error: set GITEA_TOKEN or provide ~/.git-credentials" >&2
|
|
||||||
|
if [[ ${#AUTH[@]} -eq 0 ]]; then
|
||||||
|
# Gitea Actions: actions/checkout configures a local extraheader with the
|
||||||
|
# runner's credentials. Reuse it for the API (the same server, so the header is
|
||||||
|
# valid for $HOST too).
|
||||||
|
GIT_HEADER="$(git config --local --get-regexp '^http\..*\.extraheader$' 2>/dev/null | head -n1 | cut -d' ' -f2- || true)"
|
||||||
|
if [[ -n "${GIT_HEADER:-}" ]]; then
|
||||||
|
AUTH=(-H "$GIT_HEADER")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${#AUTH[@]} -eq 0 ]]; then
|
||||||
|
echo "error: no credentials. Set GITEA_TOKEN, GITEA_AUTH_HEADER, or provide ~/.git-credentials." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -78,8 +99,31 @@ for f in "${all_artifacts[@]}"; do
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo "==> Uploading $(basename "$f")"
|
echo "==> Uploading $(basename "$f")"
|
||||||
curl -s -X POST "$API/$RELEASE_ID/assets" "${AUTH[@]}" -F "attachment=@$f" >/dev/null
|
# Fail loudly: a silent 4xx here used to leave a release with no artifacts while
|
||||||
|
# the job still reported success.
|
||||||
|
code="$(curl -sS -o /tmp/release-upload.json -w '%{http_code}' --retry 2 \
|
||||||
|
-X POST "$API/$RELEASE_ID/assets" "${AUTH[@]}" -F "attachment=@$f" || true)"
|
||||||
|
if [[ "$code" != "201" && "$code" != "200" ]]; then
|
||||||
|
echo "error: upload of $(basename "$f") failed with HTTP $code" >&2
|
||||||
|
cat /tmp/release-upload.json >&2 || true
|
||||||
|
echo "" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Verify the release actually carries the artifacts we just sent.
|
||||||
|
have="$(curl -sS "${AUTH[@]}" "$API/$RELEASE_ID" | python3 -c "
|
||||||
|
import sys, json
|
||||||
|
try:
|
||||||
|
d = json.load(sys.stdin)
|
||||||
|
except Exception:
|
||||||
|
print(0); raise SystemExit
|
||||||
|
print(len(d.get('assets', [])))" 2>/dev/null || echo 0)"
|
||||||
|
if [[ "${have:-0}" -lt "${#all_artifacts[@]}" ]]; then
|
||||||
|
echo "error: release has $have assets, expected ${#all_artifacts[@]}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Verified $have artifacts on the release"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Release live: $HOST/$REPO/releases/tag/$TAG"
|
echo "Release live: $HOST/$REPO/releases/tag/$TAG"
|
||||||
Reference in new issue
Block a user