Repository navigation
Finalize v1.0.0 public release metadata #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Finalize v1.0.0 public release | ||
| on: | ||
| push: | ||
| paths: | ||
| - '.github/workflows/v1-postrelease-finalize.yml' | ||
| permissions: | ||
| contents: write | ||
| jobs: | ||
| finalize: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout main | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| ref: main | ||
| fetch-depth: 0 | ||
| - name: Finalize repository release metadata | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| cat > release_body.md <<'EOF' | ||
| # System Shock - Android v1.0.0 | ||
| First stable preservation release of the native Android/ARM64 System Shock port based on Shockolate. | ||
| ## Stable baseline | ||
| - Native Android/ARM64 (`arm64-v8a`) | ||
| - Package: `io.github.raposomiguel50.systemshock` | ||
| - Version: `1.0.0` (`versionCode 10000`) | ||
| - 1024x768 4:3 presentation without non-uniform stretching | ||
| - Handheld controls with right-stick camera look and fine cursor mode | ||
| - Optional touchscreen pointer input | ||
| - Android IME text entry | ||
| - Android-compatible audio handling | ||
| - First-run Storage Access Framework importer for user-supplied compatible game data | ||
| - Retroid Pocket 5 validated as the reference target | ||
| - Complete start-to-finish reference-device playthrough accepted before release | ||
| The APK contains no commercial System Shock game data. Users provide compatible data from a legally obtained copy. | ||
| ## Install | ||
| 1. Install `SystemShock-Android-v1.0.0-arm64-v8a.apk`. | ||
| 2. Launch **System Shock - Android**. | ||
| 3. Select a compatible `res` folder containing `data` and `sound`. | ||
| Normal users do not need ADB or developer tools. | ||
| ## Preservation boundary | ||
| Stable v1.0 does not add widescreen/Hor+, HD replacement graphics, remastered fonts, truecolor conversion, replacement audio, gameplay rebalance or new game content. | ||
| The historical pre-release used package `com.rp5np.systemshock`. Stable v1 uses `io.github.raposomiguel50.systemshock`; both packages may coexist. The stable line has its own long-lived signing identity for future compatible updates. | ||
| ## Verified release identity | ||
| - Source commit: `d40e02b00e5e59b956b18fdd2a13a41672090b2c` | ||
| - APK SHA-256: `a6dcb7f76374dd7d4f7e39f0ecc08446f2956a33bda7655d699d5ba639b8526f` | ||
| - Signing certificate SHA-256: `806d9cb061de67aa6953cdac573bd917da6aa17625964c2898d23e226bd5323b` | ||
| - ABI: `arm64-v8a` | ||
| - Commercial game data included: **No** | ||
| The accompanying `.sha256`, JSON manifest and final-gate report provide machine-readable release evidence. | ||
| EOF | ||
| python3 - <<'PY' | ||
| from pathlib import Path | ||
| import json | ||
| source_commit = 'd40e02b00e5e59b956b18fdd2a13a41672090b2c' | ||
| apk_sha = 'a6dcb7f76374dd7d4f7e39f0ecc08446f2956a33bda7655d699d5ba639b8526f' | ||
| cert_sha = '806d9cb061de67aa6953cdac573bd917da6aa17625964c2898d23e226bd5323b' | ||
| package = 'io.github.raposomiguel50.systemshock' | ||
| p = Path('README.md') | ||
| s = p.read_text(encoding='utf-8') | ||
| s = s.replace('**Latest published APK:** [v0.1.0-pre.3](https://github.com/raposomiguel50/system-shock-android/releases/tag/v0.1.0-pre.3)', '**Latest published APK:** [v1.0.0](https://github.com/raposomiguel50/system-shock-android/releases/tag/v1.0.0)') | ||
| s = s.replace('- Source state: **v1.0.0 release candidate / preservation scope frozen**', '- Source state: **v1.0.0 stable / preservation release**') | ||
| s = s.replace('- Latest published APK until the final signed v1.0 artifact is produced: **v0.1.0-pre.3**', '- Latest published APK: **v1.0.0 stable**') | ||
| s = s.replace('- Stable signing identity: **created automatically at the first final v1.0 build, then preserved for all future stable updates**', f'- Stable signing certificate SHA-256: **`{cert_sha}`**') | ||
| old = 'Stable `v1.0.0` is **not considered published until the exact source commit passes the final signed-release machine gates and the verified APK is attached to a matching GitHub release**.' | ||
| new = f'Stable `v1.0.0` is published and verified. Release source commit: [`{source_commit[:12]}`](https://github.com/raposomiguel50/system-shock-android/commit/{source_commit}); APK SHA-256: `{apk_sha}`.' | ||
| s = s.replace(old, new) | ||
| p.write_text(s, encoding='utf-8') | ||
| p = Path('SOURCE_BASELINE.json') | ||
| data = json.loads(p.read_text(encoding='utf-8')) | ||
| data['schema'] = 4 | ||
| data.pop('release_candidate_version', None) | ||
| data.pop('release_candidate_version_code', None) | ||
| data['release_status'] = 'stable' | ||
| data['stable_release_version'] = '1.0.0' | ||
| data['stable_release_version_code'] = 10000 | ||
| data['release_source_commit'] = source_commit | ||
| data['release_apk_sha256'] = apk_sha | ||
| data['release_signing_certificate_sha256'] = cert_sha | ||
| data['release_package'] = package | ||
| data['stable_signing_policy'] = 'The dedicated v1 stable signing identity is established and must be reused for all compatible future stable updates.' | ||
| p.write_text(json.dumps(data, indent=2, ensure_ascii=False) + '\n', encoding='utf-8') | ||
| Path('docs/RELEASE_NOTES_V1.0.0.md').write_text(Path('release_body.md').read_text(encoding='utf-8'), encoding='utf-8') | ||
| Path('docs/V1_RELEASE_GATE.md').write_text(f'''# v1.0.0 release gate — complete | ||
| `v1.0.0` is the first stable preservation release of System Shock - Android. | ||
| ## Product/manual gates | ||
| - [x] Complete start-to-finish playthrough accepted on the Retroid Pocket 5 reference device. | ||
| - [x] 1024x768 4:3 no-stretch presentation accepted. | ||
| - [x] Handheld controls/fine cursor, Android text input, audio and first-run data importer accepted. | ||
| - [x] Commercial System Shock data remains outside the APK and public source. | ||
| - [x] HD, widescreen/Hor+, font-remaster, truecolor and gameplay/content changes remain outside stable-v1 scope. | ||
| ## Machine/release gates | ||
| - [x] Public GitHub Actions QA passed after the stable-package transition. | ||
| - [x] Clean local final gate reported `V1_FINAL_LOCAL_GATE=PASS`. | ||
| - [x] Pinned public dependencies resolved from a fresh checkout. | ||
| - [x] Signed non-debuggable `release` APK produced and verified. | ||
| - [x] Stable package verified: `{package}`. | ||
| - [x] Version verified: `1.0.0` / `versionCode 10000`. | ||
| - [x] ABI verified: `arm64-v8a`. | ||
| - [x] Stable certificate recorded: `{cert_sha}`. | ||
| - [x] APK SHA-256 recorded: `{apk_sha}`. | ||
| - [x] Release JSON, `.sha256` and final-gate report agree. | ||
| - [x] Tag `v1.0.0` points to source commit `{source_commit}`. | ||
| - [x] GitHub Release `v1.0.0` is public with the signed APK and evidence files. | ||
| - [x] Publicly re-downloaded APK reproduced the expected SHA-256. | ||
| ## Stable identity | ||
| - Source commit: `{source_commit}` | ||
| - Package: `{package}` | ||
| - APK SHA-256: `{apk_sha}` | ||
| - Signing certificate SHA-256: `{cert_sha}` | ||
| - Commercial game data included: `false` | ||
| The GitHub stable-release gate is complete. External mirrors/directories may be synchronized separately without changing the immutable v1.0.0 source or APK identity. | ||
| ''', encoding='utf-8') | ||
| for filename, heading in [('docs/INTEGRITY.md', 'Established v1.0.0 identity'), ('docs/RELEASE.md', 'Published v1.0.0 evidence')]: | ||
| p = Path(filename) | ||
| s = p.read_text(encoding='utf-8') | ||
| marker = f'## {heading}' | ||
| if marker not in s: | ||
| s += f'''\n\n{marker}\n\n- Source commit: `{source_commit}`\n- Stable package: `{package}`\n- APK SHA-256: `{apk_sha}`\n- Signing certificate SHA-256: `{cert_sha}`\n- GitHub release: `v1.0.0`\n- Proprietary game data included: `false`\n''' | ||
| p.write_text(s, encoding='utf-8') | ||
| PY | ||
| - name: Correct GitHub Release notes and verify assets | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| release_id="$(gh api "repos/${GITHUB_REPOSITORY}/releases/tags/v1.0.0" --jq '.id')" | ||
| gh api --method PATCH "repos/${GITHUB_REPOSITORY}/releases/${release_id}" \ | ||
| -f name='System Shock - Android v1.0.0' \ | ||
| -f body="$(cat release_body.md)" \ | ||
| -F draft=false \ | ||
| -F prerelease=false >/dev/null | ||
| body="$(gh api "repos/${GITHUB_REPOSITORY}/releases/tags/v1.0.0" --jq '.body')" | ||
| printf '%s\n' "$body" | grep -Fq 'Package: `io.github.raposomiguel50.systemshock`' | ||
| printf '%s\n' "$body" | grep -Fq 'APK SHA-256: `a6dcb7f76374dd7d4f7e39f0ecc08446f2956a33bda7655d699d5ba639b8526f`' | ||
| printf '%s\n' "$body" | grep -Fq 'Signing certificate SHA-256: `806d9cb061de67aa6953cdac573bd917da6aa17625964c2898d23e226bd5323b`' | ||
| assets="$(gh api "repos/${GITHUB_REPOSITORY}/releases/${release_id}/assets" --jq '.[].name')" | ||
| printf '%s\n' "$assets" | grep -Fxq 'SystemShock-Android-v1.0.0-arm64-v8a.apk' | ||
| printf '%s\n' "$assets" | grep -Fxq 'SystemShock-Android-v1.0.0-arm64-v8a.apk.sha256' | ||
| printf '%s\n' "$assets" | grep -Fxq 'SystemShock-Android-v1.0.0-release.json' | ||
| printf '%s\n' "$assets" | grep -Fxq 'SystemShock-Android-v1.0.0-final-gate.txt' | ||
| - name: Commit public post-release state and remove this workflow | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| rm -f .github/workflows/v1-postrelease-finalize.yml | ||
| git config user.name 'github-actions[bot]' | ||
| git config user.email '41898282+github-actions[bot]@users.noreply.github.com' | ||
| git add README.md SOURCE_BASELINE.json docs/RELEASE_NOTES_V1.0.0.md docs/V1_RELEASE_GATE.md docs/INTEGRITY.md docs/RELEASE.md .github/workflows/v1-postrelease-finalize.yml | ||
| if git diff --cached --quiet; then | ||
| exit 0 | ||
| fi | ||
| git commit -m 'Finalize v1.0.0 public release state' | ||
| git push origin HEAD:main | ||