Require both platform artifacts for releases
All checks were successful
Release builds / Linux x64 artifact (push) Successful in 2m17s
Release builds / Windows x64 artifact (push) Successful in 1m19s
Release builds / Publish tagged Gitea release (push) Has been skipped
Core validation / Linux core gate (push) Successful in 1m17s

This commit is contained in:
gamer147
2026-08-03 22:35:43 -04:00
parent 4799b48b9c
commit d657c63e57
7 changed files with 473 additions and 129 deletions

View File

@@ -142,13 +142,19 @@ release authority. Source-only workflow regressions pin those rules and preserve
platform artifact jobs completed and the tag-only promotion job was skipped. The Windows hosted artifact path is
therefore accepted; dual-platform promotion is the remaining CI/CD slice.
The next promotion slice will require both jobs, download both already-built archives, verify their commit/build
evidence, and publish two distributable release assets:
Dual-platform promotion was implemented on 2026-08-03. The tag-only job now requires both successful build jobs
and downloads their retained artifacts into separate directories without rebuilding. The release helper rechecks
both external archive hashes, exact clean tag-commit metadata and target RID, matching build metadata/payload
ledgers inside each archive, Linux's accepted dynamic package smoke, and Windows's complete static AMD64/ABI/
import report. It creates or resumes only a matching release, rejects unexpected or colliding assets, and exposes
exactly two distributable archives:
`OpenMaidEngine-Himegari-linux-x64.tar.gz` and `OpenMaidEngine-Himegari-windows-x64.zip`. A third small
`RELEASE-SHA256SUMS` attachment will authenticate both archives while keeping the release below Gitea's observed
five-attachment boundary; detailed build metadata, payload ledgers, and logs remain inside each archive and in
the retained workflow artifacts. The release notes will state that Linux received the dynamic package smoke and
Windows received structural cross-target verification only.
Windows received structural cross-target verification only. Source-only paired creation/resume/refusal tests
pass. The first hosted develop run must still prove both build jobs green and promotion skipped before the user
selects a future tag; `v0.1.0` remains unchanged.
Code signing, an installer, Windows-on-Linux execution, and retroactively modifying the accepted Linux-only
`v0.1.0` release are outside this effort. A future signing slice can use `osslsigncode` and protected credentials

View File

@@ -1085,6 +1085,16 @@ do not mix mechanical moves with semantic changes.
completed both platform artifact jobs and skipped tag-only promotion, accepting the runner/toolchain/cache/
build/upload path and the non-tag authority boundary. Slice 4 is now active.
**Slice 4 implementation completed 2026-08-03; hosted acceptance pending:** tag promotion now requires both
successful platform jobs and downloads their already-built artifacts into separate directories. The helper
binds both archives to the same clean tag commit/RID, verifies their external hashes, compares external build
metadata and payload ledgers with the copies inside each archive, requires Linux's dynamic smoke and Windows's
AMD64/ABI/import report, and generates combined release checksums. Creation and retry expose exactly three
public assets—Linux archive, Windows archive, and `RELEASE-SHA256SUMS`—while unexpected assets, release
mismatches, and same-name/different-size collisions fail without mutation. Synthetic paired-artifact,
creation/resume/refusal, and workflow-dependency tests pass. The next gate is a hosted develop run with both
builds green and promotion skipped; only after that proof may the user deliberately select a future tag.
**Completion gate:** one deliberately selected future tag produces a single Gitea release containing the
Linux `.tar.gz`, Windows `.zip`, and combined archive checksums; both archives bind to the tag commit, Linux
retains its dynamic packaged smoke, Windows passes all structural PE/payload gates, and neither platform job

View File

@@ -60,20 +60,24 @@ repository permission and have no secrets, private game corpus, or release/packa
first hosted dual-job develop run at `9d3ab30` succeeded on 2026-08-03: both platform artifacts completed and
the tag-only promotion job was skipped. This accepts the Windows artifact job and its non-tag authority boundary.
Only a successful `v*` tag run enables the dependent promotion job. It downloads that same workflow artifact
rather than rebuilding, checks out only the release tool, and receives job-local `releases: write` plus
`contents: read`; branch and manual runs skip the job and never receive release authority. The built-in
`secrets.GITEA_TOKEN` calls the native Gitea API, so no personal token or third-party release action is required.
`publish_gitea_release.py` validates the version-like tag, exact clean-build commit metadata, archive checksum,
accepted package-smoke result, fixed five-file asset set, and any
existing release/asset metadata. A retry resumes a matching partial release and uploads only missing files; it
refuses mismatched releases or same-name/different-size assets instead of editing, deleting, or overwriting them.
Only a successful `v*` tag run after both platform jobs enables the dependent promotion job. It downloads the
two verified workflow artifacts into separate directories rather than rebuilding, checks out only the release
tool, and receives job-local `releases: write` plus `contents: read`; branch and manual runs skip the job and
never receive release authority. The built-in `secrets.GITEA_TOKEN` calls the native Gitea API, so no personal
token or third-party release action is required. `publish_gitea_release.py` validates the version-like tag, both
exact clean-build commit/target records, both external archive hashes, matching metadata/ledgers inside each
archive, the accepted Linux package smoke, and the Windows AMD64/ABI/import verification. It then generates one
`RELEASE-SHA256SUMS` and publishes exactly three assets: the Linux `.tar.gz`, Windows `.zip`, and combined
checksums. Detailed evidence remains inside each archive and in retained workflow artifacts. A retry resumes a
matching partial release and uploads only missing files; it refuses mismatched releases, unexpected assets, or
same-name/different-size collisions instead of editing, deleting, or overwriting them. The first hosted develop
run of this paired promotion contract remains pending; no new version tag is created as part of that proof.
| Tool | Purpose | Run | Reads → Writes |
|---|---|---|---|
| `publish_gitea_release.py` | Tag-only, retry-safe promotion of one verified Linux workflow artifact through Gitea's native release API. Requires `GITEA_TOKEN`; the token is passed to upload `curl` through standard input rather than its argument list. | `publish_gitea_release.py --server <url> --repository <owner/name> --tag <v...> --target <sha> --asset <path>` (exactly the five expected `--asset` names) | verified downloaded workflow artifact + tag context → matching Gitea release and five attachments |
| `test_publish_gitea_release.py` | Pure synthetic creation, retry/resume, collision, and mismatch regressions. | `test_publish_gitea_release.py` | temporary files only |
| `test_release_workflow.py` | Source-only policy regression for the independent read-only Linux/Windows jobs, target-specific MinGW/cache/artifact boundary, no-Wine/no-Windows-smoke rule, and deliberately unchanged Linux-only tag promotion dependency during Windows CI/CD slice 3. | `test_release_workflow.py` | `.gitea/workflows/linux-release-build.yml` → assertions only |
| `publish_gitea_release.py` | Tag-only, retry-safe promotion of paired verified Linux/Windows workflow artifacts through Gitea's native release API. Revalidates both archives/evidence sets, writes combined release checksums, and exposes exactly three public assets. Requires `GITEA_TOKEN`; the token is passed to upload `curl` through standard input rather than its argument list. | `publish_gitea_release.py --server <url> --repository <owner/name> --tag <v...> --target <sha> --linux-artifact-directory <dir> --windows-artifact-directory <dir> --output-directory <dir>` | two verified downloaded workflow artifacts + tag context → matching Gitea release with Linux archive, Windows archive, and `RELEASE-SHA256SUMS` |
| `test_publish_gitea_release.py` | Pure synthetic paired-artifact/archive validation, three-asset creation, retry/resume, collision, unexpected-asset, and mismatch regressions. | `test_publish_gitea_release.py` | temporary files only |
| `test_release_workflow.py` | Source-only policy regression for the independent read-only Linux/Windows jobs, target-specific MinGW/cache/artifact boundary, no-Wine/no-Windows-smoke rule, and promotion's dependency/download of both successful artifacts. | `test_release_workflow.py` | `.gitea/workflows/linux-release-build.yml` → assertions only |
## Optional local binary tools