Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 131 additions & 20 deletions .github/actions/render-release-config/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,22 @@ inputs:
app:
description: Which app to render for (desktop or mobile)
required: true
publisher-repo:
description: owner/name of the config publisher repository (vars.CONFIG_PUBLISHER_REPO)
required: false
default: ""
publisher-repository:
description: Validated owner/name from vars.CONFIG_PUBLISHER_REPO
required: true
publisher-token:
description: Token that can read the config publisher repository (secrets.CONFIG_PUBLISHER_TOKEN)
description: Short-lived Contents read token restricted to publisher-repository
required: true
source-repository:
description: Validated owner/name from vars.CONFIG_SOURCE_REPO
required: true
source-token:
description: Short-lived Contents read token restricted to source-repository
required: true
source-root:
description: Reviewed source root (repository root for production or examples/acme-zenith)
required: false
default: ""
default: "."
revision:
description: Config revision metadata JSON content (vars.CONFIG_RELEASE_REVISION)
required: false
Expand Down Expand Up @@ -49,8 +57,11 @@ runs:
shell: bash
env:
APP: ${{ inputs.app }}
PUBLISHER_REPO: ${{ inputs.publisher-repo }}
PUBLISHER_REPO: ${{ inputs.publisher-repository }}
PUBLISHER_TOKEN: ${{ inputs.publisher-token }}
SOURCE_REPO: ${{ inputs.source-repository }}
SOURCE_TOKEN: ${{ inputs.source-token }}
SOURCE_ROOT: ${{ inputs.source-root }}
REVISION_JSON: ${{ inputs.revision }}
KEYRINGS_JSON: ${{ inputs.keyrings }}
MANIFEST_DESKTOP: ${{ inputs.release-manifest }}
Expand All @@ -60,9 +71,24 @@ runs:
run: |
set -euo pipefail

if [[ ! "$PUBLISHER_REPO" =~ ^arcboxlabs/[A-Za-z0-9][A-Za-z0-9._-]{0,99}$ ]]; then
echo "::error::CONFIG_PUBLISHER_REPO must use canonical arcboxlabs/repository syntax"
exit 1
fi
if [[ ! "$SOURCE_REPO" =~ ^arcboxlabs/[A-Za-z0-9][A-Za-z0-9._-]{0,99}$ ]]; then
echo "::error::CONFIG_SOURCE_REPO must use canonical arcboxlabs/repository syntax"
exit 1
fi
if [ "$PUBLISHER_REPO" = "$SOURCE_REPO" ]; then
echo "::error::CONFIG_PUBLISHER_REPO and CONFIG_SOURCE_REPO must identify different repositories"
exit 1
fi
if [ -z "$PUBLISHER_TOKEN" ] || [ -z "$SOURCE_TOKEN" ]; then
echo "::error::render-release-config requires separate short-lived Contents read tokens for $PUBLISHER_REPO and $SOURCE_REPO"
exit 1
fi

missing=()
[ -n "$PUBLISHER_REPO" ] || missing+=(CONFIG_PUBLISHER_REPO)
[ -n "$PUBLISHER_TOKEN" ] || missing+=(CONFIG_PUBLISHER_TOKEN)
[ -n "$REVISION_JSON" ] || missing+=(CONFIG_RELEASE_REVISION)
[ -n "$KEYRINGS_JSON" ] || missing+=(CONFIG_RELEASE_KEYRINGS)
case "$APP" in
Expand Down Expand Up @@ -120,27 +146,112 @@ runs:
brand="$(pin "$primary" .brandId)"
channel="$(pin "$primary" .channel)"
telemetry="$(pin "$primary" .telemetryEndpoint)"
if [[ ! "$publisher_sha" =~ ^[0-9a-f]{40}$ ]] || [[ ! "$source_sha" =~ ^[0-9a-f]{40}$ ]]; then
echo "::error::publisherGitSha and sourceGitSha must be exact lowercase 40-hex commits"
exit 1
fi

# Fetch exactly the two pinned commits — never a branch head — and keep the token out of
# persisted git config by passing it per command.
auth="AUTHORIZATION: basic $(printf 'x-access-token:%s' "$PUBLISHER_TOKEN" | base64 -w0)"
# Repository identities are release-environment owned; the source root is workflow-owned.
# Manifests control exact commits and bind the rendered release inputs.
publisher_repo="$PUBLISHER_REPO"
source_repo="$SOURCE_REPO"
case "$SOURCE_ROOT" in
.|examples/acme-zenith) ;;
*) echo "::error::source-root must be the production repository root or the reviewed nonproduction example root"; exit 1 ;;
esac
publisher="$work/publisher"
git init -q "$publisher"
git -C "$publisher" remote add origin "https://github.com/${PUBLISHER_REPO}.git"
if ! git -C "$publisher" -c "http.https://github.com/.extraheader=$auth" \
fetch -q --depth 1 origin "$publisher_sha" "$source_sha"; then
echo "::error::Could not fetch pinned commits ${publisher_sha} / ${source_sha} from the config publisher repository. Release builds require read access to the private publisher repository and both pinned commits to exist."
source="$work/source"

checkout_pinned() {
local dir="$1" repo="$2" sha="$3" token="$4" label="$5"
local auth comparison extra reviewed reviewed_name reviewed_sha
local reviewed_ref=refs/heads/master
auth="AUTHORIZATION: basic $(printf 'x-access-token:%s' "$token" | base64 -w0)"
git init -q "$dir"
git -C "$dir" remote add origin "https://github.com/${repo}.git"
if ! reviewed="$(git -C "$dir" \
-c "http.https://github.com/.extraheader=$auth" \
-c http.followRedirects=false \
ls-remote --exit-code origin "$reviewed_ref")"; then
echo "::error::Could not resolve reviewed master for $label repository $repo"
exit 1
fi
read -r reviewed_sha reviewed_name extra <<< "$reviewed"
if [[ ! "$reviewed_sha" =~ ^[0-9a-f]{40}$ ]] || \
[ "$reviewed_name" != "$reviewed_ref" ] || [ -n "$extra" ]; then
echo "::error::$label reviewed ref identity did not match $reviewed_ref in $repo"
exit 1
fi
comparison="$dir-reviewed-ancestry.json"
if ! curl --fail --silent --show-error --max-redirs 0 \
--proto '=https' --tlsv1.2 \
-H 'Accept: application/vnd.github+json' \
-H "Authorization: Bearer $token" \
-H 'X-GitHub-Api-Version: 2022-11-28' \
-o "$comparison" \
"https://api.github.com/repos/${repo}/compare/${sha}...${reviewed_sha}"; then
echo "::error::Could not verify that $label commit $sha is reachable from reviewed master in $repo"
exit 1
fi
if ! jq -e --arg sha "$sha" '
(.status == "ahead" or .status == "identical") and
.base_commit.sha == $sha and .merge_base_commit.sha == $sha
' "$comparison" > /dev/null; then
echo "::error::$label commit $sha is not reachable from reviewed master in $repo"
exit 1
fi
if ! git -C "$dir" -c "http.https://github.com/.extraheader=$auth" \
-c http.followRedirects=false \
fetch -q --depth 1 origin "$sha"; then
echo "::error::Could not fetch $label commit $sha from $repo. Confirm the org App is installed on that private repository with Contents: read and the commit exists."
exit 1
fi
git -C "$dir" checkout -q --detach FETCH_HEAD
if [ "$(git -C "$dir" rev-parse HEAD)" != "$sha" ] || \
[ "$(git -C "$dir" remote get-url origin)" != "https://github.com/${repo}.git" ]; then
echo "::error::$label checkout identity did not match expected repository $repo at $sha"
exit 1
fi
}

checkout_pinned "$publisher" "$publisher_repo" "$publisher_sha" "$PUBLISHER_TOKEN" publisher
checkout_pinned "$source" "$source_repo" "$source_sha" "$SOURCE_TOKEN" "config source"
unset PUBLISHER_TOKEN SOURCE_TOKEN

structural="$source/$SOURCE_ROOT"
if [ ! -f "$publisher/package.json" ] || \
[ ! -f "$publisher/pnpm-lock.yaml" ] || \
[ ! -f "$publisher/packages/config-publisher/package.json" ] || \
[ ! -f "$publisher/packages/config-structural/schema/config.schema.json" ] || \
[ -L "$publisher/package.json" ] || \
[ -L "$publisher/pnpm-lock.yaml" ] || \
[ -L "$publisher/packages/config-publisher/package.json" ] || \
[ -L "$publisher/packages/config-structural/schema/config.schema.json" ]; then
echo "::error::Pinned publisher checkout does not satisfy the publisher/parser/schema contract"
exit 1
fi
if [ ! -f "$structural/brands.manifest.yaml" ] || \
[ ! -f "$structural/schema/config.schema.json" ]; then
echo "::error::Pinned config source must contain source root $SOURCE_ROOT with its manifest and schema mirror; production root is intentionally unavailable until reviewed production data exists"
exit 1
fi
if find "$structural" -type l -print -quit | grep -q .; then
echo "::error::Pinned config source root must not contain symbolic links"
exit 1
fi
if ! cmp -s \
"$publisher/packages/config-structural/schema/config.schema.json" \
"$structural/schema/config.schema.json"; then
echo "::error::Config source schema mirror differs byte-for-byte from the canonical schema at publisher commit $publisher_sha"
exit 1
fi
git -C "$publisher" checkout -q "$publisher_sha"
git -C "$publisher" worktree add -q --detach "$work/source" "$source_sha"

pnpm --dir "$publisher" install --frozen-lockfile

common_args=(
--publisher "$publisher"
--publisher-git-sha "$publisher_sha"
--structural "$work/source/packages/config-structural"
--structural "$structural"
--source-git-sha "$source_sha"
--revision "$work/revision.json"
--keyrings "$work/keyrings.json"
Expand Down
24 changes: 12 additions & 12 deletions .github/release/brand-matrices/code-561-pilot.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@
"expectedSnapshotSha256": "0675b1b33e81d4898f75233fdf9bda7243348e286ebfd3b06f807d82fff8818f",
"platform": "android",
"publicKeyringsSha256": "1a674a4c47d1ef57e51f7e50e8f044f32cffa0450574f12f23ddeb5cb619d445",
"publisherGitSha": "e4a0624abbc8ed1cac4948fa90239176a83cb96e",
"publisherGitSha": "986d9f21403df53bc932f511eb1b5f0bb634d48d",
"releaseManifestFormatVersion": 1,
"revisionSha256": "e8389e2edc8273c5ec1b029c7101ae18af6e5b55218f0c8fd2dfe640cf695c5b",
"sourceGitSha": "e4a0624abbc8ed1cac4948fa90239176a83cb96e",
"sourceGitSha": "a1ed4d666721c3aed0d563aaea42fce8b5f945b5",
"telemetryEndpoint": "https://acme.example.invalid/telemetry"
},
"desktop": {
Expand All @@ -79,10 +79,10 @@
"expectedSnapshotSha256": "936250a3ef922cede3a200b5dc401cc7697ee1db90dc3efd0f873358524f01e3",
"platform": "desktop",
"publicKeyringsSha256": "1a674a4c47d1ef57e51f7e50e8f044f32cffa0450574f12f23ddeb5cb619d445",
"publisherGitSha": "e4a0624abbc8ed1cac4948fa90239176a83cb96e",
"publisherGitSha": "986d9f21403df53bc932f511eb1b5f0bb634d48d",
"releaseManifestFormatVersion": 1,
"revisionSha256": "e8389e2edc8273c5ec1b029c7101ae18af6e5b55218f0c8fd2dfe640cf695c5b",
"sourceGitSha": "e4a0624abbc8ed1cac4948fa90239176a83cb96e",
"sourceGitSha": "a1ed4d666721c3aed0d563aaea42fce8b5f945b5",
"telemetryEndpoint": "https://acme.example.invalid/telemetry"
},
"ios": {
Expand All @@ -92,10 +92,10 @@
"expectedSnapshotSha256": "a689a8d95f74d9cb00b5d9850af3ecfd50edb23d2496c71805c9ffe4659d56ae",
"platform": "ios",
"publicKeyringsSha256": "1a674a4c47d1ef57e51f7e50e8f044f32cffa0450574f12f23ddeb5cb619d445",
"publisherGitSha": "e4a0624abbc8ed1cac4948fa90239176a83cb96e",
"publisherGitSha": "986d9f21403df53bc932f511eb1b5f0bb634d48d",
"releaseManifestFormatVersion": 1,
"revisionSha256": "e8389e2edc8273c5ec1b029c7101ae18af6e5b55218f0c8fd2dfe640cf695c5b",
"sourceGitSha": "e4a0624abbc8ed1cac4948fa90239176a83cb96e",
"sourceGitSha": "a1ed4d666721c3aed0d563aaea42fce8b5f945b5",
"telemetryEndpoint": "https://acme.example.invalid/telemetry"
}
}
Expand Down Expand Up @@ -165,10 +165,10 @@
"expectedSnapshotSha256": "a0ef5196645ae3b857343784f7a5ab5d6f5184b15c7cb646d8e86c93ff5384b0",
"platform": "android",
"publicKeyringsSha256": "1a674a4c47d1ef57e51f7e50e8f044f32cffa0450574f12f23ddeb5cb619d445",
"publisherGitSha": "e4a0624abbc8ed1cac4948fa90239176a83cb96e",
"publisherGitSha": "986d9f21403df53bc932f511eb1b5f0bb634d48d",
"releaseManifestFormatVersion": 1,
"revisionSha256": "e8389e2edc8273c5ec1b029c7101ae18af6e5b55218f0c8fd2dfe640cf695c5b",
"sourceGitSha": "e4a0624abbc8ed1cac4948fa90239176a83cb96e",
"sourceGitSha": "a1ed4d666721c3aed0d563aaea42fce8b5f945b5",
"telemetryEndpoint": "https://zenith.example.invalid/telemetry"
},
"desktop": {
Expand All @@ -178,10 +178,10 @@
"expectedSnapshotSha256": "99a93cec0ca5381faa15a5def6727736f220b5d7d111e1fce04afda1d321aef2",
"platform": "desktop",
"publicKeyringsSha256": "1a674a4c47d1ef57e51f7e50e8f044f32cffa0450574f12f23ddeb5cb619d445",
"publisherGitSha": "e4a0624abbc8ed1cac4948fa90239176a83cb96e",
"publisherGitSha": "986d9f21403df53bc932f511eb1b5f0bb634d48d",
"releaseManifestFormatVersion": 1,
"revisionSha256": "e8389e2edc8273c5ec1b029c7101ae18af6e5b55218f0c8fd2dfe640cf695c5b",
"sourceGitSha": "e4a0624abbc8ed1cac4948fa90239176a83cb96e",
"sourceGitSha": "a1ed4d666721c3aed0d563aaea42fce8b5f945b5",
"telemetryEndpoint": "https://zenith.example.invalid/telemetry"
},
"ios": {
Expand All @@ -191,10 +191,10 @@
"expectedSnapshotSha256": "e1b93b64973e0192ed2e1d8ba9a4cca27ae2bb5521ef6011392c2d86b510b95b",
"platform": "ios",
"publicKeyringsSha256": "1a674a4c47d1ef57e51f7e50e8f044f32cffa0450574f12f23ddeb5cb619d445",
"publisherGitSha": "e4a0624abbc8ed1cac4948fa90239176a83cb96e",
"publisherGitSha": "986d9f21403df53bc932f511eb1b5f0bb634d48d",
"releaseManifestFormatVersion": 1,
"revisionSha256": "e8389e2edc8273c5ec1b029c7101ae18af6e5b55218f0c8fd2dfe640cf695c5b",
"sourceGitSha": "e4a0624abbc8ed1cac4948fa90239176a83cb96e",
"sourceGitSha": "a1ed4d666721c3aed0d563aaea42fce8b5f945b5",
"telemetryEndpoint": "https://zenith.example.invalid/telemetry"
}
}
Expand Down
Loading
Loading