name: Validate trusted Mantis ref description: Resolve Mantis refs and require trusted repository provenance inputs: candidate-ref: description: Candidate ref, tag, or SHA to validate required: true baseline-ref: description: Optional baseline ref, tag, or SHA to validate required: false default: "" outputs: candidate-revision: description: Resolved candidate commit SHA value: ${{ steps.validate.outputs.candidate_revision }} baseline-revision: description: Resolved baseline commit SHA, or empty when no baseline was supplied value: ${{ steps.validate.outputs.baseline_revision }} runs: using: composite steps: - name: Validate refs are trusted id: validate env: BASELINE_REF: ${{ inputs.baseline-ref }} CANDIDATE_REF: ${{ inputs.candidate-ref }} shell: bash run: | set -euo pipefail git fetch --no-tags origin +refs/heads/main:refs/remotes/origin/main validate_ref() { local label="$1" local input_ref="$2" local revision="" local reason="" revision="$(git rev-parse "${input_ref}^{commit}")" if git merge-base --is-ancestor "$revision" refs/remotes/origin/main; then reason="main-ancestor" elif git tag --points-at "$revision" | grep -Eq '^v'; then reason="release-tag" else local pr_head_count pr_head_count="$( gh api \ -H "Accept: application/vnd.github+json" \ "repos/${GITHUB_REPOSITORY}/commits/${revision}/pulls" \ --jq '[.[] | select(.state == "open" and .head.repo.full_name == "'"${GITHUB_REPOSITORY}"'" and .head.sha == "'"${revision}"'")] | length' )" if [[ "$pr_head_count" != "0" ]]; then reason="open-pr-head" fi fi if [[ -z "$reason" ]]; then echo "${label} ref '${input_ref}' resolved to ${revision}, which is not trusted for this secret-bearing Mantis run." >&2 exit 1 fi echo "${label}_revision=${revision}" >> "$GITHUB_OUTPUT" { echo "${label}: \`${input_ref}\`" echo "${label} SHA: \`${revision}\`" echo "${label} trust reason: \`${reason}\`" } >> "$GITHUB_STEP_SUMMARY" } if [[ -n "$BASELINE_REF" ]]; then validate_ref baseline "$BASELINE_REF" fi validate_ref candidate "$CANDIDATE_REF"