Merge remote-tracking branch 'origin/main' into gsd/phase-13-real-lint-gate-eslint
# Conflicts: # .planning/ROADMAP.md
This commit is contained in:
@@ -303,5 +303,11 @@ jobs:
|
||||
uses: https://github.com/ChristopherHX/gitea-upload-artifact@v4
|
||||
with:
|
||||
name: playwright-traces-${{ github.run_id }}
|
||||
path: apps/pwa/test-results/
|
||||
# Upload BOTH the raw traces/screenshots/videos (test-results/) AND the
|
||||
# navigable HTML report (playwright-report/, built by --reporter=list,html).
|
||||
# Without the report dir the most useful triage artifact for a remote CI
|
||||
# failure is built on every run and then discarded at runner teardown (WR-02).
|
||||
path: |
|
||||
apps/pwa/test-results/
|
||||
apps/pwa/playwright-report/
|
||||
retention-days: 14
|
||||
|
||||
@@ -41,6 +41,12 @@ jobs:
|
||||
- name: Compute image tags
|
||||
id: tags
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Fail closed if GITHUB_SHA is empty/unset (Gitea runner env parity is not
|
||||
# guaranteed across versions). Without this guard SHORT_SHA degrades to ""
|
||||
# and the immutable tag silently becomes :v1.1- — a valid-but-wrong tag that
|
||||
# overwrites the milestone pointer and destroys rollback traceability (WR-03).
|
||||
: "${GITHUB_SHA:?GITHUB_SHA is empty — refusing to build a malformed image tag}"
|
||||
SHORT_SHA=${GITHUB_SHA:0:7}
|
||||
MILESTONE="${{ env.MILESTONE }}"
|
||||
echo "latest=git.bergerhouse.net/luckberg/familysync-api:latest" >> $GITHUB_OUTPUT
|
||||
@@ -53,8 +59,15 @@ jobs:
|
||||
# Secret is named REGISTRY_PAT (not GITEA_REGISTRY_PAT): Gitea reserves the GITEA_ prefix
|
||||
# for secret names, so the GITEA_-prefixed name cannot be created.
|
||||
- name: Docker login
|
||||
# Bind the secret through env: so it is never substituted into the rendered
|
||||
# script body. Read it as $REGISTRY_PAT and pipe with printf '%s' (echo is not
|
||||
# safe for arbitrary strings — a trailing newline or shell-significant char
|
||||
# would mangle the password into a confusing `unauthorized`) (WR-05).
|
||||
env:
|
||||
REGISTRY_PAT: ${{ secrets.REGISTRY_PAT }}
|
||||
run: |
|
||||
echo "${{ secrets.REGISTRY_PAT }}" | \
|
||||
set -euo pipefail
|
||||
printf '%s' "$REGISTRY_PAT" | \
|
||||
docker login git.bergerhouse.net \
|
||||
--username luckberg \
|
||||
--password-stdin
|
||||
@@ -63,13 +76,18 @@ jobs:
|
||||
# lockfile from the root context; building from apps/api/ would fail to find them.
|
||||
- name: Build and push
|
||||
run: |
|
||||
set -euo pipefail
|
||||
docker build --target production \
|
||||
-f apps/api/Dockerfile \
|
||||
-t ${{ steps.tags.outputs.latest }} \
|
||||
-t ${{ steps.tags.outputs.sha_tag }} \
|
||||
.
|
||||
docker push ${{ steps.tags.outputs.latest }}
|
||||
docker push ${{ steps.tags.outputs.sha_tag }}
|
||||
# Push the IMMUTABLE :<milestone>-<sha> tag FIRST. set -euo pipefail stops on
|
||||
# the first failed push, so :latest is only moved after the immutable,
|
||||
# rollback-traceable tag has landed — a failed second push can never leave
|
||||
# :latest advanced without a corresponding rollback tag (WR-04).
|
||||
docker push ${{ steps.tags.outputs.sha_tag }} # immutable first
|
||||
docker push ${{ steps.tags.outputs.latest }} # move pointer only after immutable lands
|
||||
|
||||
# Always drop the stored credential from the runner after push (defence in depth).
|
||||
- name: Docker logout
|
||||
|
||||
Reference in New Issue
Block a user