mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-13 11:39:41 +03:00
204 lines
6.9 KiB
YAML
204 lines
6.9 KiB
YAML
name: bot-nix-hashes
|
|
|
|
# Keeps nix/hashes.json in step with the lockfile through a pull request, using only GITHUB_TOKEN.
|
|
# - hash and compute run repository code (nix build) with a read-only token and no secrets. compute uploads only the
|
|
# new nix/hashes.json.
|
|
# - publish holds the write token. It runs only .github/nix-hashes/ from this commit, treats the artifact as data,
|
|
# validates its exact shape and commits only that file to bot/nix-hashes. It never runs repository code.
|
|
# - check-bot-scope.yml, a required check, fails the bot's pull request unless it changes only a valid nix/hashes.json,
|
|
# so a tampered branch cannot auto-merge.
|
|
# This file, check-bot-scope.yml and .github/nix-hashes/ are the security boundary.
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
push:
|
|
branches: [dev]
|
|
# Mirrored in .github/nix-hashes/publish.sh.
|
|
paths:
|
|
- "bun.lock"
|
|
- "package.json"
|
|
- "packages/*/package.json"
|
|
- "services/*/package.json"
|
|
- "flake.lock"
|
|
- "nix/node_modules.nix"
|
|
- "nix/scripts/**"
|
|
- "patches/**"
|
|
- ".github/workflows/bot-nix-hashes.yml"
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
# Native runners required: bun install cross-compilation flags (--os/--cpu)
|
|
# do not produce byte-identical node_modules as native installs.
|
|
hash:
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- system: x86_64-linux
|
|
runner: blacksmith-4vcpu-ubuntu-2404
|
|
- system: aarch64-linux
|
|
runner: blacksmith-4vcpu-ubuntu-2404-arm
|
|
- system: aarch64-darwin
|
|
runner: macos-latest
|
|
runs-on: ${{ matrix.runner }}
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Nix
|
|
uses: nixbuild/nix-quick-install-action@2c9db80fb984ceb1bcaa77cdda3fdf8cfba92035 # v34
|
|
|
|
- name: Compute node_modules hash
|
|
id: hash
|
|
env:
|
|
SYSTEM: ${{ matrix.system }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
BUILD_LOG=$(mktemp)
|
|
trap 'rm -f "$BUILD_LOG"' EXIT
|
|
|
|
HASH=""
|
|
MAX_ATTEMPTS=3
|
|
for ((ATTEMPT = 1; ATTEMPT <= MAX_ATTEMPTS; ATTEMPT++)); do
|
|
# Build with fakeHash to trigger hash mismatch and reveal correct hash
|
|
nix build ".#packages.${SYSTEM}.node_modules_updater" --no-link 2>&1 | tee "$BUILD_LOG" || true
|
|
|
|
HASH="$(nix run --inputs-from . nixpkgs#gnugrep -- -oP 'got:\s*\Ksha256-[A-Za-z0-9+/=]+' "$BUILD_LOG" | tail -n1 || true)"
|
|
|
|
[ -n "$HASH" ] && break
|
|
|
|
if [ "$ATTEMPT" -lt "$MAX_ATTEMPTS" ]; then
|
|
echo "::warning::Attempt ${ATTEMPT}/${MAX_ATTEMPTS} produced no hash for ${SYSTEM}; retrying in $((ATTEMPT * 10))s"
|
|
sleep $((ATTEMPT * 10))
|
|
fi
|
|
done
|
|
|
|
if [ -z "$HASH" ]; then
|
|
echo "::error::Failed to compute hash for ${SYSTEM} after ${MAX_ATTEMPTS} attempts"
|
|
cat "$BUILD_LOG"
|
|
exit 1
|
|
fi
|
|
|
|
echo "$HASH" > hash.txt
|
|
echo "Computed hash for ${SYSTEM}: $HASH"
|
|
|
|
- name: Upload hash
|
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
with:
|
|
name: hash-${{ matrix.system }}
|
|
path: hash.txt
|
|
retention-days: 1
|
|
|
|
# Assembles nix/hashes.json from the per-system hashes and uploads it as the only input publish accepts.
|
|
compute:
|
|
needs: hash
|
|
runs-on: ubuntu-24.04
|
|
outputs:
|
|
changed: ${{ steps.update.outputs.changed }}
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Download hash artifacts
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
path: ${{ runner.temp }}/hashes
|
|
pattern: hash-*
|
|
|
|
- name: Update hashes.json
|
|
id: update
|
|
env:
|
|
HASHES: ${{ runner.temp }}/hashes
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
HASH_FILE="nix/hashes.json"
|
|
|
|
[ -f "$HASH_FILE" ] || echo '{"nodeModules":{}}' > "$HASH_FILE"
|
|
|
|
for SYSTEM in x86_64-linux aarch64-linux aarch64-darwin; do
|
|
HASH="$(tr -d '[:space:]' < "$HASHES/hash-${SYSTEM}/hash.txt")"
|
|
echo "${SYSTEM}: ${HASH}"
|
|
jq --arg sys "$SYSTEM" --arg h "$HASH" '.nodeModules[$sys] = $h' "$HASH_FILE" > tmp.json
|
|
mv tmp.json "$HASH_FILE"
|
|
done
|
|
|
|
cat "$HASH_FILE"
|
|
bash .github/nix-hashes/validate.sh "$HASH_FILE"
|
|
|
|
if git diff --quiet -- "$HASH_FILE"; then
|
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
echo "### Nix hashes" >> "$GITHUB_STEP_SUMMARY"
|
|
echo "Status: no changes" >> "$GITHUB_STEP_SUMMARY"
|
|
else
|
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
echo "### Nix hashes" >> "$GITHUB_STEP_SUMMARY"
|
|
echo "Status: changed" >> "$GITHUB_STEP_SUMMARY"
|
|
fi
|
|
|
|
- name: Upload hashes.json
|
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
with:
|
|
name: nix-hashes
|
|
path: nix/hashes.json
|
|
if-no-files-found: error
|
|
retention-days: 1
|
|
|
|
# Runs even when compute found no change, so an open bot pull request with stale hashes is closed, not merged.
|
|
publish:
|
|
needs: compute
|
|
if: github.repository == 'anomalyco/opencode' && github.ref == 'refs/heads/dev'
|
|
runs-on: ubuntu-24.04
|
|
concurrency:
|
|
group: bot-nix-hashes-publish
|
|
cancel-in-progress: false
|
|
permissions:
|
|
contents: write
|
|
pull-requests: write
|
|
actions: write
|
|
|
|
steps:
|
|
- name: Check out publish scripts
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
with:
|
|
ref: ${{ github.sha }}
|
|
path: trusted
|
|
sparse-checkout: /.github/nix-hashes/
|
|
sparse-checkout-cone-mode: false
|
|
persist-credentials: false
|
|
|
|
# Holds the push credential; only nix/hashes.json is checked out and nothing in it runs.
|
|
- name: Check out dev
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
with:
|
|
ref: dev
|
|
path: repo
|
|
sparse-checkout: /nix/hashes.json
|
|
sparse-checkout-cone-mode: false
|
|
|
|
- name: Download hashes.json
|
|
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
with:
|
|
name: nix-hashes
|
|
path: ${{ runner.temp }}/nix-hashes
|
|
|
|
- name: Publish
|
|
working-directory: repo
|
|
run: bash ../trusted/.github/nix-hashes/publish.sh "$RUNNER_TEMP/nix-hashes/hashes.json"
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
GH_REPO: ${{ github.repository }}
|