mirror of
https://relay.ngit.dev/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp.git
synced 2026-10-05 15:08:24 +00:00
Motivation: Release images should be built, checked, published, and consumed through the same Nostr-native OCI path operators will use, without relying on an unreviewed local release procedure. Approach: Add a checked-in container manifest, a Docker-to-OCI layout helper, automatic tag publication and pull verification, a safe exact-tag backfill workflow, and deployment CI that imports and runs the exact generated layout. Correctness: Release tags come only from reviewed OCI index annotations; ordinary publication preserves prior tags; historical backfills cannot move latest or prerelease channels; generated images and temporary resources use bounded, validated names and cleanup. Excluded scope: This change does not alter ngit-grasp runtime behavior, change package versions, create v3.0.2, publish a container, move a release tag, or run the heavyweight container build in the coding VM. Validation: git diff --check; shellcheck on all container scripts; actionlint on all affected workflows; ngit parsing of .ngit/containers.yaml; canonical source and v3.0.1 tag resolution. The PR pipeline performs the full OCI build, import, and deployment test. Assisted-by: Codex (GPT-5)
146 lines
5.3 KiB
YAML
146 lines
5.3 KiB
YAML
on:
|
|
push:
|
|
tags: ["v*"]
|
|
|
|
name: release assets
|
|
|
|
jobs:
|
|
linux-x86_64:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 60
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
- uses: danconwaydev/setup-ngit@v3
|
|
- uses: cachix/install-nix-action@v31
|
|
with:
|
|
nix_path: nixpkgs=channel:nixos-unstable
|
|
- name: Require the disposable guest container daemon
|
|
shell: bash
|
|
run: |
|
|
if [[ ! -S /var/run/docker.sock ]]; then
|
|
echo "container daemon socket is not available" >&2
|
|
echo "this workflow requires an ngit-ci operator opt-in" >&2
|
|
exit 1
|
|
fi
|
|
- name: Restore Nix store cache
|
|
continue-on-error: true
|
|
uses: nix-community/cache-nix-action@v7
|
|
with:
|
|
primary-key: release-nix-${{ runner.os }}-${{ hashFiles('**/*.nix', 'flake.lock') }}
|
|
restore-prefixes-first-match: release-nix-${{ runner.os }}-
|
|
# cache-nix-action requires a token even with purge disabled;
|
|
# github.token is empty under ngit-ci, so any non-empty value works.
|
|
token: unused
|
|
- name: Build static binary
|
|
run: nix build .#static --out-link result-static
|
|
- name: Package release asset
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
version="${GITHUB_REF_NAME#v}"
|
|
if [[ -z "$version" || "$version" == *[!A-Za-z0-9._+-]* ]]; then
|
|
echo "unsupported release version from tag: $GITHUB_REF_NAME" >&2
|
|
exit 1
|
|
fi
|
|
package_version="$(nix eval --raw .#static.version)"
|
|
if [[ "$version" != "$package_version" ]]; then
|
|
echo "tag version $version does not match package version $package_version" >&2
|
|
exit 1
|
|
fi
|
|
|
|
target="x86_64-unknown-linux-musl"
|
|
archive="ngit-grasp-${version}-${target}"
|
|
source_date_epoch="$(git show -s --format=%ct "$GITHUB_SHA")"
|
|
|
|
install -Dm755 result-static/bin/ngit-grasp \
|
|
"release-stage/${archive}/ngit-grasp"
|
|
install -Dm644 LICENSE "release-stage/${archive}/LICENSE"
|
|
|
|
mkdir -p dist
|
|
tar --sort=name --mtime="@${source_date_epoch}" \
|
|
--owner=0 --group=0 --numeric-owner -C release-stage \
|
|
-czf "dist/${archive}.tar.gz" "$archive"
|
|
- name: Build OCI image layout
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
version="${GITHUB_REF_NAME#v}"
|
|
revision="$(git rev-parse "${GITHUB_REF_NAME}^{commit}")"
|
|
nix shell nixpkgs#docker-client nixpkgs#jq nixpkgs#skopeo \
|
|
--command scripts/build-container-layout.sh "$version" "$revision"
|
|
- name: Upload release assets
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: ngit-grasp-release-assets
|
|
path: dist/*.tar.gz
|
|
if-no-files-found: error
|
|
- name: Publish OCI container
|
|
shell: bash
|
|
env:
|
|
NGIT_PUBLISHER_NBUNKSEC: ${{ secrets.NGIT_PUBLISHER_NBUNKSEC }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
: "${NGIT_PUBLISHER_NBUNKSEC:?Set the NGIT_PUBLISHER_NBUNKSEC repository secret}"
|
|
|
|
umask 077
|
|
signer_file="$RUNNER_TEMP/ngit-container-nbunksec"
|
|
trap 'rm -f "$signer_file"' EXIT
|
|
printf '%s\n' "$NGIT_PUBLISHER_NBUNKSEC" > "$signer_file"
|
|
|
|
ngit container publish ngit-grasp \
|
|
--repo nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/relay.ngit.dev/ngit-grasp \
|
|
--manifest .ngit/containers.yaml \
|
|
--nbunksec-file "$signer_file" \
|
|
--defaults \
|
|
--repo-relay-only \
|
|
--json
|
|
- name: Pull and verify the published image
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
version="${GITHUB_REF_NAME#v}"
|
|
nix shell nixpkgs#docker-client \
|
|
--command scripts/verify-published-container.sh "$version"
|
|
- name: Publish NIP-82 release
|
|
shell: bash
|
|
env:
|
|
NGIT_PUBLISHER_NBUNKSEC: ${{ secrets.NGIT_PUBLISHER_NBUNKSEC }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
: "${NGIT_PUBLISHER_NBUNKSEC:?Set the NGIT_PUBLISHER_NBUNKSEC repository secret}"
|
|
|
|
umask 077
|
|
signer_file="$RUNNER_TEMP/ngit-release-nbunksec"
|
|
trap 'rm -f "$signer_file"' EXIT
|
|
printf '%s\n' "$NGIT_PUBLISHER_NBUNKSEC" > "$signer_file"
|
|
|
|
version="${GITHUB_REF_NAME#v}"
|
|
if [[ "$version" == *-* ]]; then
|
|
prerelease="${version#*-}"
|
|
channel="${prerelease%%[.+]*}"
|
|
else
|
|
channel=main
|
|
fi
|
|
released_at="$(git for-each-ref \
|
|
--format='%(creatordate:unix)' \
|
|
"refs/tags/$GITHUB_REF_NAME")"
|
|
if [[ ! "$released_at" =~ ^[0-9]+$ ]]; then
|
|
echo "could not derive release date from tag $GITHUB_REF_NAME" >&2
|
|
exit 1
|
|
fi
|
|
ngit release publish "$version" \
|
|
--repo nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/relay.ngit.dev/ngit-grasp \
|
|
--manifest .ngit/release.yaml \
|
|
--channel "$channel" \
|
|
--tag "$GITHUB_REF_NAME" \
|
|
--released-at "$released_at" \
|
|
--nbunksec-file "$signer_file" \
|
|
--defaults \
|
|
--repo-relay-only \
|
|
--json
|