Skip to content

finalize

finalize #79

Workflow file for this run

---
name: finalize
on:
workflow_run:
workflows:
- CI
types:
- completed
permissions:
actions: read
checks: write
contents: read
pull-requests: read
statuses: write
jobs:
sonar:
name: sonar
if: |
github.repository == 'redhat-developer/abbenay' &&
github.event.workflow_run.conclusion == 'success' &&
(github.event.workflow_run.event == 'pull_request' ||
(github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'main'))
runs-on: ubuntu-latest
steps:
- name: Create check run
id: create-check
uses: actions/github-script@d746ffe35508b1917358783b479e04febd2b8f71 # v9.0.0
with:
result-encoding: string
script: |
const check = await github.rest.checks.create({
owner: context.repo.owner,
repo: context.repo.repo,
name: 'sonar',
head_sha: '${{ github.event.workflow_run.head_sha }}',
status: 'in_progress',
details_url: `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
});
console.log(`In progress check created with ID: ${check.data.id}`);
return check.data.id;
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
with:
ref: ${{ github.event.workflow_run.head_sha }}
repository: ${{ github.event.workflow_run.head_repository.full_name }}
fetch-depth: 0
show-progress: false
persist-credentials: false
allow-unsafe-pr-checkout: true
- name: Download coverage artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: sonar-coverage
path: packages/daemon/coverage
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
- name: Resolve PR metadata
if: github.event.workflow_run.event == 'pull_request'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
HEAD_REPOSITORY: ${{ github.event.workflow_run.head_repository.full_name }}
REPO: ${{ github.repository }}
# Trusted GitHub payload — not PR-controlled artifact content
PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }}
run: |
set -euo pipefail
if [[ -z "${PR_NUMBER}" ]]; then
PR_NUMBER=$(gh api \
-H "Accept: application/vnd.github+json" \
"repos/${REPO}/commits/${HEAD_SHA}/pulls" \
--jq '.[0].number // empty')
fi
# Fork PR head SHAs are often missing from the commits/{sha}/pulls API
# and workflow_run.pull_requests. Resolve via trusted head owner:branch,
# then require an exact head OID match (fail if 0 or >1).
if [[ ! "${PR_NUMBER}" =~ ^[0-9]+$ ]]; then
if [[ -z "${HEAD_BRANCH}" || -z "${HEAD_REPOSITORY}" ]]; then
echo "::error::Missing workflow_run head_branch/head_repository for SHA ${HEAD_SHA}"
exit 1
fi
HEAD_OWNER="${HEAD_REPOSITORY%%/*}"
MATCHES=$(gh api \
-H "Accept: application/vnd.github+json" \
"repos/${REPO}/pulls?state=open&head=${HEAD_OWNER}:${HEAD_BRANCH}" \
--jq "[.[] | select(.head.sha == \"${HEAD_SHA}\") | .number]")
MATCH_COUNT=$(jq 'length' <<< "${MATCHES}")
if [[ "${MATCH_COUNT}" -ne 1 ]]; then
echo "::error::Expected exactly one open PR for ${HEAD_OWNER}:${HEAD_BRANCH}@${HEAD_SHA}, found ${MATCH_COUNT}: ${MATCHES}"
exit 1
fi
PR_NUMBER=$(jq -r '.[0]' <<< "${MATCHES}")
fi
if [[ ! "${PR_NUMBER}" =~ ^[0-9]+$ ]]; then
echo "::error::Unable to resolve a trusted PR number for head SHA ${HEAD_SHA}"
exit 1
fi
PR_DATA=$(gh api "repos/${REPO}/pulls/${PR_NUMBER}")
PR_BASE=$(jq -r '.base.ref' <<< "${PR_DATA}")
PR_HEAD=$(jq -r '.head.ref' <<< "${PR_DATA}")
if [[ -z "${PR_BASE}" || "${PR_BASE}" == "null" || -z "${PR_HEAD}" || "${PR_HEAD}" == "null" ]]; then
echo "::error::Unable to resolve PR branch metadata for PR ${PR_NUMBER}"
exit 1
fi
{
echo "PR_NUMBER=${PR_NUMBER}"
echo "PR_BASE=${PR_BASE}"
echo "PR_HEAD=${PR_HEAD}"
} >> "${GITHUB_ENV}"
echo "Resolved PR #${PR_NUMBER} (${PR_HEAD} -> ${PR_BASE})"
- name: Prepare SonarCloud args
if: hashFiles('packages/daemon/coverage/lcov.info') != ''
shell: bash
env:
WORKFLOW_EVENT: ${{ github.event.workflow_run.event }}
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
REPO_NAME: ${{ github.repository }}
run: |
set -euo pipefail
IFS="/" read -r REPO_OWNER REPO_NAME_ONLY <<< "${REPO_NAME}"
# Pin endpoint; PRs must not override via sonar-project.properties
SONAR_ARGS="-Dsonar.host.url=https://sonarcloud.io"
SONAR_ARGS="${SONAR_ARGS} -Dsonar.projectKey=${REPO_OWNER}_${REPO_NAME_ONLY} -Dsonar.organization=${REPO_OWNER}"
SONAR_ARGS="${SONAR_ARGS} -Dsonar.scm.revision=${COMMIT_SHA}"
if [[ "${WORKFLOW_EVENT}" == "pull_request" ]]; then
if [[ ! "${PR_NUMBER:-}" =~ ^[0-9]+$ ]]; then
echo "::error::PR_NUMBER is missing or invalid"
exit 1
fi
SONAR_ARGS="${SONAR_ARGS} -Dsonar.pullrequest.key=${PR_NUMBER}"
SONAR_ARGS="${SONAR_ARGS} -Dsonar.pullrequest.branch=${PR_HEAD}"
SONAR_ARGS="${SONAR_ARGS} -Dsonar.pullrequest.base=${PR_BASE}"
fi
echo "SONAR_ARGS=${SONAR_ARGS}" >> "${GITHUB_ENV}"
- name: Check for coverage files
run: |
if [ -f packages/daemon/coverage/lcov.info ]; then
echo "Coverage Data: Available"
ls -la packages/daemon/coverage/lcov.info
else
echo "Coverage Data: Not available - exiting"
exit 1
fi
echo "Running SonarCloud analysis..."
- name: SonarCloud Scan
if: env.SONAR_ARGS != ''
uses: SonarSource/sonarqube-scan-action@22918119ff8e1ca75a623e15c8296b6ea4fbe28f # v8
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
args: ${{ env.SONAR_ARGS }}
- name: Update check run (success)
if: success()
uses: actions/github-script@d746ffe35508b1917358783b479e04febd2b8f71 # v9.0.0
with:
script: |
const isPullRequest = '${{ github.event.workflow_run.event }}' === 'pull_request';
const prNumber = process.env.PR_NUMBER;
const summary = isPullRequest && prNumber
? `SonarCloud analysis passed for PR #${prNumber}.`
: 'SonarCloud analysis passed.';
await github.rest.checks.update({
owner: context.repo.owner,
repo: context.repo.repo,
check_run_id: ${{ steps.create-check.outputs.result }},
status: 'completed',
conclusion: 'success',
completed_at: new Date().toISOString(),
details_url: `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
output: {
title: 'SonarCloud analysis passed',
summary,
},
});
- name: Update check run (failure)
if: failure() && steps.create-check.outcome == 'success'
uses: actions/github-script@d746ffe35508b1917358783b479e04febd2b8f71 # v9.0.0
with:
script: |
const isPullRequest = '${{ github.event.workflow_run.event }}' === 'pull_request';
const prNumber = process.env.PR_NUMBER;
const summary = isPullRequest && prNumber
? `SonarCloud analysis failed for PR #${prNumber}. Click Details for logs.`
: 'SonarCloud analysis failed. Click Details for logs.';
await github.rest.checks.update({
owner: context.repo.owner,
repo: context.repo.repo,
check_run_id: ${{ steps.create-check.outputs.result }},
status: 'completed',
conclusion: 'failure',
completed_at: new Date().toISOString(),
details_url: `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
output: {
title: 'SonarCloud analysis failed',
summary,
text: `**Workflow run:** [View details](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})`,
},
});