Compute APM credential-group matrix |
compute |
| AW_APM_PACKAGES |
AW_APM_APPS |
AW_APM_LEGACY_APP_ID |
AW_APM_LEGACY_PRIVATE_KEY |
AW_APM_LEGACY_OWNER |
AW_APM_LEGACY_REPOS |
${{ github.aw.import-inputs.packages }} |
${{ github.aw.import-inputs.apps }} |
${{ github.aw.import-inputs.app-id }} |
${{ github.aw.import-inputs.private-key }} |
${{ github.aw.import-inputs.owner }} |
${{ github.aw.import-inputs.repositories }} |
|
set -euo pipefail
packages_json=${AW_APM_PACKAGES:-null}
apps_json=${AW_APM_APPS:-null}
legacy_id=${AW_APM_LEGACY_APP_ID:-}
# gh-aw substitutes `${{ github.aw.import-inputs.packages }}` at
# compile time using Go's default slice formatter, which emits
# `[a b c]` (space-separated, no quotes) instead of valid JSON.
# That breaks `jq --argjson` below. Repair string-array inputs
# in place; leave already-valid JSON untouched. apps[] (objects)
# is not repairable this way -- consumers must use the legacy
# single-app inputs until upstream gh-aw exposes a JSON-encoding
# helper for import-inputs.
repair_string_array() {
local raw="$1"
if [ -z "$raw" ] || [ "$raw" = "null" ]; then
echo "$raw"; return
fi
if printf '%s' "$raw" | jq -e 'type=="array"' >/dev/null 2>&1; then
echo "$raw"; return
fi
python3 -c 'import json, re, sys; s=sys.argv[1].strip(); s=s[1:-1] if s.startswith("[") and s.endswith("]") else s; print(json.dumps([t for t in re.split(r"[\s,]+", s) if t]))' "$raw"
}
packages_json=$(repair_string_array "$packages_json")
groups=$(jq -nc \
--argjson packages "$packages_json" \
--argjson apps "$apps_json" \
--arg legacy_id "$legacy_id" \
--arg legacy_pk "${AW_APM_LEGACY_PRIVATE_KEY:-}" \
--arg legacy_owner "${AW_APM_LEGACY_OWNER:-}" \
--arg legacy_repos "${AW_APM_LEGACY_REPOS:-}" \
'def slug(s): s | gsub("[^a-zA-Z0-9-]"; "-") | ascii_downcase | .[0:32];
def with_id(g):
g + (if (g.id // "") == "" then {id: ("auto-" + slug(g.owner // "default"))} else {} end);
[
(if (($packages // []) | length) > 0 and $legacy_id == ""
then [{id:"default",("app-id"):"",("private-key"):"",owner:"",repositories:"",packages:$packages}]
else [] end),
(if $legacy_id != ""
then [with_id({id:"legacy",("app-id"):$legacy_id,("private-key"):$legacy_pk,owner:$legacy_owner,repositories:$legacy_repos,packages:($packages // [])})]
else [] end),
(($apps // []) | map(with_id(.)))
] | add // []')
count=$(echo "$groups" | jq 'length')
if [ "$count" = "0" ]; then
echo "::error::shared/apm.md import provided no packages. Add packages: <list>, single-app inputs (app-id + private-key), or apps: <list> in the with: block."
exit 1
fi
dups=$(echo "$groups" | jq -r '[.[].id] | group_by(.) | map(select(length > 1) | first) | join(", ")')
if [ -n "$dups" ]; then
echo "::error::duplicate apm group ids after auto-derivation: $dups. Set apps[].id explicitly when two entries share the same owner."
exit 1
fi
while IFS= read -r id; do
if ! echo "$id" | grep -Eq '^[a-z0-9-]{1,32}$'; then
echo "::error::invalid apm group id: '$id' (lowercase alphanumeric and dashes, 1-32 chars). Set apps[].id explicitly."
exit 1
fi
done < <(echo "$groups" | jq -r '.[].id')
# SAFE: emit only id + package-count to logs. Never $groups in full.
{
echo "matrix={\"group\":$groups}"
} >> "$GITHUB_OUTPUT"
printf "::notice::APM matrix: %d credential group(s)\n" "$count"
echo "$groups" | jq -r '.[] | " - " + .id + " (" + (.packages | length | tostring) + " package(s))"'
|