diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml index e08a93f..312da22 100644 --- a/.github/workflows/init.yml +++ b/.github/workflows/init.yml @@ -26,17 +26,25 @@ permissions: jobs: init: runs-on: ubuntu-latest + steps: - - name: Validate admin token is present + - name: Preflight validation shell: bash run: | set -euo pipefail + if [ -z "${{ secrets.MOKO_ADMIN_TOKEN }}" ]; then echo "ERROR: Missing secret MOKO_ADMIN_TOKEN." + echo "Action required: Add it at repo scope: Settings -> Secrets and variables -> Actions -> New repository secret." exit 1 fi - - name: Create environment and set variables + if [ -z "${{ github.api_url }}" ] || [ -z "${{ github.server_url }}" ]; then + echo "ERROR: Missing GitHub runtime context (github.api_url or github.server_url)." + exit 1 + fi + + - name: Create environment and set variables (robust) env: GH_TOKEN: ${{ secrets.MOKO_ADMIN_TOKEN }} ENV_NAME: ${{ github.event.inputs.environment_name }} @@ -47,45 +55,85 @@ jobs: SERVER_URL: ${{ github.server_url }} OWNER: ${{ github.repository_owner }} REPO: ${{ github.event.repository.name }} + RUN_ID: ${{ github.run_id }} shell: bash run: | set -euo pipefail + die() { + echo "ERROR: $1" >&2 + exit 1 + } + + require() { + local name="$1" + local val="$2" + if [ -z "${val}" ]; then + die "Missing required value: ${name}" + fi + } + + # Do not echo GH_TOKEN + require "GH_TOKEN" "${GH_TOKEN}" + require "ENV_NAME" "${ENV_NAME}" + require "API_URL" "${API_URL}" + require "SERVER_URL" "${SERVER_URL}" + require "OWNER" "${OWNER}" + require "REPO" "${REPO}" + + # Determine which repo hosts updates.xml if [ -n "${UPDATE_XML_REPO_INPUT}" ]; then UPDATE_XML_REPO="${UPDATE_XML_REPO_INPUT}" else UPDATE_XML_REPO="${OWNER}/${REPO}" fi + require "UPDATE_XML_BRANCH" "${UPDATE_XML_BRANCH}" + require "UPDATE_XML_PATH" "${UPDATE_XML_PATH}" + + # Construct the canonical file URL that downstream workflows parse UPDATESERVER_FILE_URL="${SERVER_URL}/${UPDATE_XML_REPO}/blob/${UPDATE_XML_BRANCH}/${UPDATE_XML_PATH}" echo "Target environment: ${ENV_NAME}" echo "Variable UPDATESERVER_FILE_URL: ${UPDATESERVER_FILE_URL}" - echo "Creating or updating environment..." - curl -sS -f -X PUT \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${GH_TOKEN}" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - "${API_URL}/repos/${OWNER}/${REPO}/environments/${ENV_NAME}" \ - -d '{}' \ - -o /tmp/env_response.json + # Lightweight JSON escaper for the variable payload + json_escape() { + python - << 'PY' +import json, os, sys +print(json.dumps(sys.stdin.read())[1:-1]) +PY + } - echo "Environment API response:" - cat /tmp/env_response.json || true - echo "" + # API caller that captures status and body for auditability + api_call() { + local method="$1" + local url="$2" + local data_file="$3" # optional path to JSON file + local out_file="$4" - echo "Creating or updating environment variable..." - curl -sS -f -X PUT \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${GH_TOKEN}" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - "${API_URL}/repos/${OWNER}/${REPO}/environments/${ENV_NAME}/variables/UPDATESERVER_FILE_URL" \ - -d "{\"name\":\"UPDATESERVER_FILE_URL\",\"value\":\"${UPDATESERVER_FILE_URL}\"}" \ - -o /tmp/var_response.json + local args=( + -sS + -o "${out_file}" + -w "%{http_code}" + -X "${method}" + -H "Accept: application/vnd.github+json" + -H "Authorization: Bearer ${GH_TOKEN}" + -H "X-GitHub-Api-Version: 2022-11-28" + ) - echo "Variable API response:" - cat /tmp/var_response.json || true - echo "" + if [ -n "${data_file}" ]; then + args+=( -H "Content-Type: application/json" --data-binary "@${data_file}" ) + fi - echo "Applied: ${ENV_NAME}.UPDATESERVER_FILE_URL" + curl "${args[@]}" "${url}" + } + + print_hint_for_403() { + echo "" + echo "403 troubleshooting checklist:" + echo "- Token resource owner must be the organization that owns the repo." + echo "- Token must be approved by the org if fine grained token approvals are enabled." + echo "- Token must have Administration read/write for environments." + echo "- Token must have Actions read/write for environment variables." + echo "- If org uses SSO, token must be SSO-authorized."