From 857def468e4818e7e1265df7ec7044edf15ac6bb Mon Sep 17 00:00:00 2001 From: grloper Date: Fri, 9 Oct 2026 21:23:58 +0300 Subject: [PATCH 1/3] ci(release): create a draft GitHub Release with tarball, .deb and checksums on tags --- .github/workflows/release.yml | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 56a8f83..46762fd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,3 +53,42 @@ jobs: target/dist/DebSHA256SUMS retention-days: 30 if-no-files-found: error + + draft-release: + # Only for tag pushes; workflow_dispatch remains an artifact-only dry run. + # Creates a DRAFT release: a maintainer must review and publish it manually. + if: startsWith(github.ref, 'refs/tags/v') + needs: linux-x86_64 + runs-on: ubuntu-22.04 + timeout-minutes: 10 + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + - name: Validate tag matches package version + run: | + python3 - <<'PY' + import os, pathlib, re + version = re.search(r'^version = "([^"]+)"', pathlib.Path('Cargo.toml').read_text(), re.M).group(1) + assert os.environ['GITHUB_REF_NAME'] == f'v{version}', 'tag/package version mismatch' + PY + - uses: actions/download-artifact@v4 + with: + name: wraith-linux-x86_64 + path: dist + - name: Verify checksums before attaching + working-directory: dist + run: | + ls -l + sha256sum -c SHA256SUMS + sha256sum -c DebSHA256SUMS + - name: Create draft GitHub Release + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release create "$GITHUB_REF_NAME" \ + --draft --verify-tag \ + --title "$GITHUB_REF_NAME" \ + --notes "Draft release for $GITHUB_REF_NAME. Review CHANGELOG.md and SECURITY.md before publishing. Verify downloads with the attached checksums." \ + dist/wraith-linux-x86_64.tar.gz dist/wraith_*_amd64.deb \ + dist/SHA256SUMS dist/DebSHA256SUMS From ee33bc947b048e3908a73da74994a52492fa903a Mon Sep 17 00:00:00 2001 From: grloper Date: Fri, 9 Oct 2026 21:52:34 +0300 Subject: [PATCH 2/3] ci(release): robust version check via cargo metadata+jq, main-reachability, exact dist file check --- .github/workflows/release.yml | 43 ++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 46762fd..3f024b1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,11 +30,8 @@ jobs: - name: Validate tag matches package version if: startsWith(github.ref, 'refs/tags/') run: | - python3 - <<'PY' - import os, pathlib, re - version = re.search(r'^version = "([^"]+)"', pathlib.Path('Cargo.toml').read_text(), re.M).group(1) - assert os.environ['GITHUB_REF_NAME'] == f'v{version}', 'tag/package version mismatch' - PY + version=$(cargo metadata --no-deps --format-version 1 | jq -er '.packages[0].version') + [ "$GITHUB_REF_NAME" = "v${version}" ] || { echo "::error::tag $GITHUB_REF_NAME != v${version}"; exit 1; } - name: Full quality gates run: bash scripts/verify.sh && timeout 120 bash demo.sh - name: Assemble sensor-only archive and checksums @@ -65,21 +62,45 @@ jobs: contents: write steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Validate tag matches package version + shell: bash + run: | + set -euo pipefail + version=$(cargo metadata --no-deps --format-version 1 | jq -er '.packages[0].version') + [ "$GITHUB_REF_NAME" = "v${version}" ] || { echo "::error::tag $GITHUB_REF_NAME != v${version}"; exit 1; } + - name: Verify tagged commit is reachable from origin/main run: | - python3 - <<'PY' - import os, pathlib, re - version = re.search(r'^version = "([^"]+)"', pathlib.Path('Cargo.toml').read_text(), re.M).group(1) - assert os.environ['GITHUB_REF_NAME'] == f'v{version}', 'tag/package version mismatch' - PY + set -euo pipefail + git fetch --no-tags origin main + if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then + echo "::error::$GITHUB_SHA ($GITHUB_REF_NAME) is not reachable from origin/main; refusing to draft a release" + exit 1 + fi + # download-artifact@v4 pairs with upload-artifact@v4 (same artifact backend) + # used by the build job. If dependabot #12 bumps upload-artifact to v6, + # bump this to download-artifact@v7 in the same change (v6 <-> v7, both node24). - uses: actions/download-artifact@v4 with: name: wraith-linux-x86_64 path: dist - - name: Verify checksums before attaching + - name: Verify exactly the expected release files exist working-directory: dist + shell: bash run: | + set -euo pipefail ls -l + shopt -s nullglob + debs=(wraith_*_amd64.deb) + [ "${#debs[@]}" -eq 1 ] || { echo "::error::expected exactly one wraith_*_amd64.deb, found ${#debs[@]}"; exit 1; } + expected=$(printf '%s\n' DebSHA256SUMS SHA256SUMS wraith-linux-x86_64.tar.gz "${debs[0]}" | sort) + actual=$(find . -maxdepth 1 -type f -printf '%f\n' | sort) + [ "$expected" = "$actual" ] || { echo "::error::unexpected dist contents"; diff <(echo "$expected") <(echo "$actual") || true; exit 1; } + - name: Verify checksums before attaching + working-directory: dist + run: | + set -euo pipefail sha256sum -c SHA256SUMS sha256sum -c DebSHA256SUMS - name: Create draft GitHub Release From ddcfab22a6d2081013b29b6e29fff43d8efd1dac Mon Sep 17 00:00:00 2001 From: grloper <72247422+grloper@users.noreply.github.com> Date: Fri, 9 Oct 2026 22:41:47 +0300 Subject: [PATCH 3/3] ci(release): bump download-artifact to v7 (pairs with upload-artifact v6) and checkout to v7 --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3f024b1..f270b2c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -61,7 +61,7 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: fetch-depth: 0 - name: Validate tag matches package version @@ -81,7 +81,7 @@ jobs: # download-artifact@v4 pairs with upload-artifact@v4 (same artifact backend) # used by the build job. If dependabot #12 bumps upload-artifact to v6, # bump this to download-artifact@v7 in the same change (v6 <-> v7, both node24). - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v7 with: name: wraith-linux-x86_64 path: dist