Skip to content
Closed
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
208 changes: 208 additions & 0 deletions .github/workflows/finalize.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
---
name: finalize
on:
workflow_run:
workflows:
- CI
types:
- completed

permissions:
actions: read
checks: write
contents: read
pull-requests: read
statuses: write
Comment on lines +10 to +15

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 }}
Comment on lines +54 to +60

- 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 }}
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. Match an open PR by head OID instead.
if [[ ! "${PR_NUMBER}" =~ ^[0-9]+$ ]]; then
PR_NUMBER=$(gh pr list --repo "${REPO}" --state open --limit 100 \
--json number,headRefOid \
--jq ".[] | select(.headRefOid == \"${HEAD_SHA}\") | .number" \
| head -n1)
Comment on lines +83 to +86
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})`,
},
});