Skip to content

Finalize v1.0.0 public release metadata #1

Finalize v1.0.0 public release metadata

Finalize v1.0.0 public release metadata #1

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.

Check failure on line 110 in .github/workflows/v1-postrelease-finalize.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/v1-postrelease-finalize.yml

Invalid workflow file

You have an error in your yaml syntax on line 110
## 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