mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
150 lines
6.0 KiB
Bash
Executable File
150 lines
6.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Run release-staging.yml (and the reusable build-desktop.yml it calls) under
|
|
# act, our local GitHub Actions runner. Reads secrets/vars from
|
|
# scripts/ci-secrets.json (gitignored), regenerates the dotenv-format
|
|
# .secrets / .vars files act consumes, and fakes a workflow_dispatch event
|
|
# from the staging branch.
|
|
#
|
|
# Usage:
|
|
# bash scripts/act-staging.sh [extra act args]
|
|
# Examples:
|
|
# bash scripts/act-staging.sh -j prepare-build # only the bump+tag job
|
|
# bash scripts/act-staging.sh --list # list jobs that would run
|
|
# bash scripts/act-staging.sh -n # dry run
|
|
#
|
|
# Notes
|
|
# - The workflow's `Enforce main branch` step compares `github.ref` against
|
|
# `refs/heads/main`; the event payload below sets that.
|
|
# - act maps `runs-on: macos-latest` / `windows-latest` to linux containers
|
|
# by default. Real macOS notarization / Windows MSI signing cannot run here.
|
|
# For local debugging, restrict to `-j prepare-build` or pair with a
|
|
# matrix-platform filter via `--matrix settings.platform:ubuntu-22.04`.
|
|
# - `git push origin main` and tag pushes inside the container will hit the
|
|
# real GitHub remote with the inherited token — every full run produces a
|
|
# real `vX.Y.Z-staging` tag and a real bump commit on upstream `main`.
|
|
# To avoid that, either pass `-n` for a dry run, or scope to a read-only
|
|
# slice with `--list` / a job that has no side effects.
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
SECRETS_JSON="${ROOT}/scripts/ci-secrets.json"
|
|
SECRETS_FILE="${ROOT}/.secrets"
|
|
VARS_FILE="${ROOT}/.vars"
|
|
EVENT_FILE="${ROOT}/.github/act-event.json"
|
|
ACTRC_FILE="${ROOT}/.actrc"
|
|
|
|
if [ ! -f "$SECRETS_JSON" ]; then
|
|
echo "Missing $SECRETS_JSON" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v jq >/dev/null 2>&1; then
|
|
echo "jq is required (brew install jq)." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v act >/dev/null 2>&1; then
|
|
echo "act is required (brew install act)." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# act parses .secrets / .vars with a Go dotenv reader that supports
|
|
# double-quoted values with `\n` escapes — the only sane way to ship the
|
|
# PEM-formatted GitHub App private key. Use node so we can emit JSON
|
|
# strings ("...") that the parser will read back losslessly.
|
|
emit_dotenv() {
|
|
local key="$1"
|
|
local out="$2"
|
|
node -e '
|
|
const fs = require("fs");
|
|
const data = JSON.parse(fs.readFileSync(process.argv[1], "utf8"))[process.argv[2]] || {};
|
|
const lines = Object.entries(data).map(([k, v]) => `${k}=${JSON.stringify(String(v))}`);
|
|
fs.writeFileSync(process.argv[3], lines.join("\n") + "\n", { mode: 0o600 });
|
|
' "$SECRETS_JSON" "$key" "$out"
|
|
}
|
|
|
|
echo "[act-staging] regenerating $SECRETS_FILE"
|
|
emit_dotenv secrets "$SECRETS_FILE"
|
|
# act expects `GITHUB_TOKEN`; the JSON stores it under `GITHUB_TOKEN_` (or
|
|
# `XGH_TOKEN`) so the hostshell's `GITHUB_TOKEN` env doesn't clash with `gh`.
|
|
# Append a translated alias if either source key is present.
|
|
node -e '
|
|
const fs = require("fs");
|
|
const s = JSON.parse(fs.readFileSync(process.argv[1], "utf8")).secrets || {};
|
|
const tok = s.GITHUB_TOKEN_ || s.XGH_TOKEN;
|
|
if (tok) fs.appendFileSync(process.argv[2], `GITHUB_TOKEN=${JSON.stringify(String(tok))}\n`);
|
|
' "$SECRETS_JSON" "$SECRETS_FILE"
|
|
chmod 600 "$SECRETS_FILE"
|
|
|
|
echo "[act-staging] regenerating $VARS_FILE"
|
|
emit_dotenv vars "$VARS_FILE"
|
|
chmod 600 "$VARS_FILE"
|
|
|
|
echo "[act-staging] regenerating $ACTRC_FILE"
|
|
# Pinned in the script (not committed) because `.actrc` is in .gitignore;
|
|
# every developer's local act invocation goes through this script anyway.
|
|
cat > "$ACTRC_FILE" <<'ACTRC'
|
|
--container-architecture linux/amd64
|
|
-P ubuntu-22.04=catthehacker/ubuntu:act-22.04
|
|
-P ubuntu-latest=catthehacker/ubuntu:act-22.04
|
|
-P macos-latest=catthehacker/ubuntu:act-22.04
|
|
-P windows-latest=catthehacker/ubuntu:act-22.04
|
|
--pull=false
|
|
# Reuse cached action source under ~/.cache/act/ instead of re-cloning on
|
|
# every run. Required because act 0.2.87's go-git client always tries HTTP
|
|
# basic auth and gets 401 from github.com whether or not GITHUB_TOKEN is
|
|
# set (--token is not a CLI flag in 0.2.87). To refresh a cached action,
|
|
# delete the corresponding folder under ~/.cache/act/ and run with --pull.
|
|
--action-offline-mode
|
|
ACTRC
|
|
|
|
echo "[act-staging] regenerating $EVENT_FILE"
|
|
mkdir -p "$(dirname "$EVENT_FILE")"
|
|
# release-staging.yml's `Enforce main branch` step requires `github.ref ==
|
|
# refs/heads/main` — staging cuts and production both bump and tag from
|
|
# main. Set the dispatch ref accordingly.
|
|
cat > "$EVENT_FILE" <<'JSON'
|
|
{
|
|
"ref": "refs/heads/main",
|
|
"ref_name": "main",
|
|
"ref_type": "branch",
|
|
"repository": {
|
|
"name": "openhuman",
|
|
"full_name": "tinyhumansai/openhuman",
|
|
"default_branch": "main"
|
|
},
|
|
"inputs": {}
|
|
}
|
|
JSON
|
|
|
|
# act uses GITHUB_TOKEN from the env / secret context to authenticate the
|
|
# go-git clones it performs for third-party actions (e.g.
|
|
# tibdex/github-app-token@v1). Prefer the local `gh` CLI token here — it's
|
|
# the user's OAuth token and has unrestricted public-repo read access. The
|
|
# fine-grained PAT in ci-secrets.json is scoped to this repo only and gets
|
|
# rejected with "Invalid username or token" on cross-repo action clones.
|
|
if command -v gh >/dev/null 2>&1; then
|
|
GH_AUTH_TOKEN="$(gh auth token 2>/dev/null || true)"
|
|
if [ -n "$GH_AUTH_TOKEN" ]; then
|
|
export GITHUB_TOKEN="$GH_AUTH_TOKEN"
|
|
fi
|
|
fi
|
|
if [ -z "${GITHUB_TOKEN:-}" ]; then
|
|
echo "[act-staging] warning: no GITHUB_TOKEN available — third-party action clones may 401." >&2
|
|
fi
|
|
|
|
# act derives `github.repository` from the local checkout's parent dirs
|
|
# (so a fork like `senamakel/openhuman` becomes the value). Pin it to the
|
|
# upstream slug so steps that look up the GitHub App installation
|
|
# (`tibdex/github-app-token`) and that hit the GitHub API for the right
|
|
# repo (`gh release upload`, `gh api packages/...`) target the same repo
|
|
# CI sees in production.
|
|
exec act workflow_dispatch \
|
|
-W "${ROOT}/.github/workflows/release-staging.yml" \
|
|
--eventpath "$EVENT_FILE" \
|
|
--secret-file "$SECRETS_FILE" \
|
|
--var-file "$VARS_FILE" \
|
|
--env GITHUB_REPOSITORY=tinyhumansai/openhuman \
|
|
--env GITHUB_REPOSITORY_OWNER=tinyhumansai \
|
|
"$@"
|