Wire Forge-native release infrastructure
Some checks failed
Cache: Publish Nix / Publish Nix Cache (push) Waiting to run
Build Rust / Cargo Test (push) Successful in 4m14s
Build Site / Next.js Build (push) Failing after 6s
Infra: OpenTofu / OpenTofu (grafana) (push) Successful in 5s
Lint Governance / BEP Metadata (push) Successful in 0s
Build: Android / Android Rust Core Stub (push) Failing after 23s
Some checks failed
Cache: Publish Nix / Publish Nix Cache (push) Waiting to run
Build Rust / Cargo Test (push) Successful in 4m14s
Build Site / Next.js Build (push) Failing after 6s
Infra: OpenTofu / OpenTofu (grafana) (push) Successful in 5s
Lint Governance / BEP Metadata (push) Successful in 0s
Build: Android / Android Rust Core Stub (push) Failing after 23s
This commit is contained in:
parent
97c569fb35
commit
002bd382e9
199 changed files with 14268 additions and 185 deletions
205
Scripts/forgejo-dispatch-via-host.sh
Executable file
205
Scripts/forgejo-dispatch-via-host.sh
Executable file
|
|
@ -0,0 +1,205 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: Scripts/forgejo-dispatch-via-host.sh <workflow> [--ref <ref>] [--inputs <json>] [--inputs-file <path>] [--return-run-info]
|
||||
|
||||
Dispatch a Burrow Forgejo workflow by SSHing to the live forge host and using
|
||||
the managed dispatcher token from the host runtime.
|
||||
|
||||
Environment:
|
||||
FORGEJO_BASE_URL Default: https://git.burrow.net
|
||||
FORGEJO_REPO Default: hackclub/burrow
|
||||
BURROW_FORGE_HOST Default: root@git.burrow.net
|
||||
BURROW_FORGE_HOST_ADDRESS Optional SSH HostName override
|
||||
BURROW_FORGE_SSH_KEY Optional explicit SSH private key
|
||||
AGE_FORGE_SSH_KEY Optional injected SSH private key material
|
||||
BURROW_FORGE_DISPATCHER_CONFIG_FILE Default: /run/agenix/burrowForgejoNscDispatcherConfig
|
||||
EOF
|
||||
}
|
||||
|
||||
base_url="${FORGEJO_BASE_URL:-https://git.burrow.net}"
|
||||
repo_slug="${FORGEJO_REPO:-hackclub/burrow}"
|
||||
forge_host="${BURROW_FORGE_HOST:-root@git.burrow.net}"
|
||||
forge_host_address="${BURROW_FORGE_HOST_ADDRESS:-}"
|
||||
dispatcher_config_file="${BURROW_FORGE_DISPATCHER_CONFIG_FILE:-/run/agenix/burrowForgejoNscDispatcherConfig}"
|
||||
workflow=""
|
||||
ref="main"
|
||||
inputs_json=""
|
||||
return_run_info="false"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
--ref)
|
||||
ref="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--inputs)
|
||||
inputs_json="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--inputs-file)
|
||||
inputs_json="$(cat "${2:-}")"
|
||||
shift 2
|
||||
;;
|
||||
--return-run-info)
|
||||
return_run_info="true"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
if [[ -z "$workflow" ]]; then
|
||||
workflow="$1"
|
||||
shift
|
||||
else
|
||||
echo "Unexpected argument: $1" >&2
|
||||
usage >&2
|
||||
exit 64
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z "$workflow" ]]; then
|
||||
echo "Missing workflow name or file, for example build-release.yml." >&2
|
||||
usage >&2
|
||||
exit 64
|
||||
fi
|
||||
|
||||
script_dir="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
resolved_forge_ssh_key="$("${script_dir}/resolve-forge-ssh-key.sh")"
|
||||
eval "$resolved_forge_ssh_key"
|
||||
ssh_key="${BURROW_FORGE_SSH_KEY}"
|
||||
|
||||
if [[ -n "$inputs_json" ]]; then
|
||||
if ! python3 - "$inputs_json" <<'PY' >/dev/null
|
||||
import json
|
||||
import sys
|
||||
|
||||
value = json.loads(sys.argv[1])
|
||||
if not isinstance(value, dict):
|
||||
raise SystemExit(1)
|
||||
PY
|
||||
then
|
||||
echo "--inputs must be a JSON object." >&2
|
||||
exit 64
|
||||
fi
|
||||
fi
|
||||
|
||||
workflow_path="$(python3 - "$workflow" <<'PY'
|
||||
import sys
|
||||
import urllib.parse
|
||||
|
||||
print(urllib.parse.quote(sys.argv[1], safe=""))
|
||||
PY
|
||||
)"
|
||||
|
||||
payload="$(python3 - "$ref" "$inputs_json" "$return_run_info" <<'PY'
|
||||
import json
|
||||
import sys
|
||||
|
||||
ref = sys.argv[1]
|
||||
inputs_arg = sys.argv[2]
|
||||
return_run_info = sys.argv[3] == "true"
|
||||
|
||||
payload = {"ref": ref}
|
||||
if inputs_arg:
|
||||
inputs = json.loads(inputs_arg)
|
||||
payload["inputs"] = {key: str(value) for key, value in inputs.items()}
|
||||
if return_run_info:
|
||||
payload["return_run_info"] = True
|
||||
print(json.dumps(payload))
|
||||
PY
|
||||
)"
|
||||
|
||||
payload_b64="$(python3 - "$payload" <<'PY'
|
||||
import base64
|
||||
import sys
|
||||
|
||||
print(base64.b64encode(sys.argv[1].encode()).decode())
|
||||
PY
|
||||
)"
|
||||
|
||||
ssh_opts=(
|
||||
-i "$ssh_key"
|
||||
-o IdentitiesOnly=yes
|
||||
-o UserKnownHostsFile=/dev/null
|
||||
-o GlobalKnownHostsFile=/dev/null
|
||||
-o StrictHostKeyChecking=accept-new
|
||||
)
|
||||
if [[ -n "$forge_host_address" ]]; then
|
||||
ssh_opts+=(-o "HostName=$forge_host_address")
|
||||
fi
|
||||
|
||||
response="$(
|
||||
ssh "${ssh_opts[@]}" "$forge_host" bash -s -- \
|
||||
"$base_url" "$repo_slug" "$workflow_path" "$dispatcher_config_file" "$payload_b64" <<'EOF'
|
||||
set -euo pipefail
|
||||
|
||||
base_url="$1"
|
||||
repo_slug="$2"
|
||||
workflow_path="$3"
|
||||
dispatcher_config_file="$4"
|
||||
payload_b64="$5"
|
||||
|
||||
payload="$(python3 - "$payload_b64" <<'PY'
|
||||
import base64
|
||||
import sys
|
||||
|
||||
print(base64.b64decode(sys.argv[1]).decode())
|
||||
PY
|
||||
)"
|
||||
|
||||
if [[ ! -s "$dispatcher_config_file" ]]; then
|
||||
echo "Forge dispatcher config is missing or empty: $dispatcher_config_file" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
runtime_token="$(
|
||||
awk '
|
||||
/^[A-Za-z0-9_-]+:/ { in_forgejo = ($0 ~ /^forgejo:/); next }
|
||||
in_forgejo && /^[[:space:]]+token:/ {
|
||||
sub(/^[[:space:]]+token:[[:space:]]*/, "")
|
||||
gsub(/^"/, "")
|
||||
gsub(/"$/, "")
|
||||
gsub(/^\047/, "")
|
||||
gsub(/\047$/, "")
|
||||
print
|
||||
exit
|
||||
}
|
||||
' "$dispatcher_config_file" | tr -d "\r\n"
|
||||
)"
|
||||
|
||||
if [[ -z "$runtime_token" ]]; then
|
||||
echo "Forge dispatcher token not found in $dispatcher_config_file" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
url="${base_url%/}/api/v1/repos/${repo_slug}/actions/workflows/${workflow_path}/dispatches"
|
||||
response_file="$(mktemp)"
|
||||
http_code="$(
|
||||
curl -sS -o "$response_file" -w '%{http_code}' -X POST \
|
||||
-H "Authorization: token ${runtime_token}" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary "$payload" \
|
||||
"$url"
|
||||
)"
|
||||
if [[ "$http_code" != 2* ]]; then
|
||||
cat "$response_file" >&2
|
||||
rm -f "$response_file"
|
||||
exit 22
|
||||
fi
|
||||
cat "$response_file"
|
||||
rm -f "$response_file"
|
||||
EOF
|
||||
)"
|
||||
|
||||
if [[ "$return_run_info" == "true" ]]; then
|
||||
printf '%s\n' "$response"
|
||||
else
|
||||
echo "Dispatched ${workflow} on ${ref} via ${forge_host}."
|
||||
fi
|
||||
Loading…
Add table
Add a link
Reference in a new issue