ci: add automated releases and tags (#9) #15
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
# This action is centrally managed in https://github.com/<organization>/.github/ | |
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in | |
# the above-mentioned repo. | |
name: Qodana | |
on: | |
pull_request: | |
branches: [master, nightly] | |
types: [opened, synchronize, reopened] | |
push: | |
branches: [master, nightly] | |
workflow_dispatch: | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: true | |
jobs: | |
qodana_initial_check: | |
name: Qodana Initial Check | |
permissions: | |
actions: write # required to use workflow dispatch on fork PRs | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Prepare | |
id: prepare | |
run: | | |
# check the branch variable | |
if [ "${{ github.event_name }}" == "push" ] | |
then | |
echo "This is a PUSH event" | |
# use the branch name | |
destination=${{ github.ref_name }} | |
target=${{ github.ref_name }} | |
else | |
echo "This is a PR event" | |
# use the PR number | |
destination=${{ github.event.pull_request.number }} | |
target=${{ github.event.pull_request.base.ref }} | |
fi | |
echo "checkout_repo=$checkout_repo" >> $GITHUB_OUTPUT | |
echo "checkout_ref=$checkout_ref" >> $GITHUB_OUTPUT | |
echo "destination=$destination" >> $GITHUB_OUTPUT | |
echo "target=$target" >> $GITHUB_OUTPUT | |
# prepare urls | |
base=https://${{ github.repository_owner }}.github.io | |
report_url=${base}/qodana-reports/${{ github.event.repository.name }}/${destination} | |
echo "report_url=$report_url" >> $GITHUB_OUTPUT | |
# build matrix | |
files=$(find . -type f -iname "qodana*.yaml") | |
echo "files: ${files}" | |
# do not quote to keep this as a single line | |
echo files=${files} >> $GITHUB_OUTPUT | |
MATRIX_COMBINATIONS="" | |
REPORTS_MARKDOWN="" | |
for FILE in ${files}; do | |
# extract the language from file name after `qodana-` and before `.yaml` | |
language=$(echo $FILE | sed -r -z -e 's/(\.\/)*.*\/(qodana.yaml)/default/gm') | |
if [[ $language != "default" ]]; then | |
language=$(echo $FILE | sed -r -z -e 's/(\.\/)*.*qodana-(.*).yaml/\2/gm') | |
fi | |
MATRIX_COMBINATIONS="$MATRIX_COMBINATIONS {\"file\": \"$FILE\", \"language\": \"$language\"}," | |
REPORTS_MARKDOWN="$REPORTS_MARKDOWN <br> - [${language}](${report_url}/${language})" | |
done | |
# removes the last character (i.e. comma) | |
MATRIX_COMBINATIONS=${MATRIX_COMBINATIONS::-1} | |
# setup matrix for later jobs | |
matrix=$(( | |
echo "{ \"include\": [$MATRIX_COMBINATIONS] }" | |
) | jq -c .) | |
echo $matrix | |
echo $matrix | jq . | |
echo "matrix=$matrix" >> $GITHUB_OUTPUT | |
echo "reports_markdown=$REPORTS_MARKDOWN" >> $GITHUB_OUTPUT | |
- name: Setup initial notification inputs | |
id: inputs | |
if: >- | |
startsWith(github.event_name, 'pull_request') && | |
steps.prepare.outputs.files != '' | |
run: | | |
# workflow logs | |
workflow_url_a=https://github.com/${{ github.repository_owner }}/${{ github.event.repository.name }} | |
workflow_url=${workflow_url_a}/actions/runs/${{ github.run_id }} | |
# multiline message | |
message=$(cat <<- EOF | |
:warning: **Qodana is checking this PR** :warning: | |
Live results available [here](${workflow_url}) | |
EOF | |
) | |
# escape json control characters | |
message=$(jq -n --arg message "$message" '$message' | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g') | |
secondary_inputs=$(echo '{ | |
"issue_message": "'"${message}"'", | |
"issue_message_id": "'"qodana"'", | |
"issue_number": "'"${{ github.event.number }}"'", | |
"issue_repo_owner": "'"${{ github.repository_owner }}"'", | |
"issue_repo_name": "'"${{ github.event.repository.name }}"'" | |
}' | jq -r .) | |
#escape json control characters | |
secondary_inputs=$(jq -n --arg secondary_inputs "$secondary_inputs" '$secondary_inputs' \ | |
| sed -e 's/\\/\\\\/g' -e 's/"/\\"/g') | |
echo $secondary_inputs | |
# secondary input as string, not JSON | |
# todo - change dispatch_ref to master instead of nightly | |
primary_inputs=$(echo '{ | |
"dispatch_repository": "'"${{ github.repository_owner }}/.github"'", | |
"dispatch_workflow": "'"dispatch-issue-comment.yml"'", | |
"dispatch_ref": "'"nightly"'", | |
"dispatch_inputs": "'"${secondary_inputs}"'" | |
}' | jq -c .) | |
echo $primary_inputs | |
echo $primary_inputs | jq . | |
echo "primary_inputs=$primary_inputs" >> $GITHUB_OUTPUT | |
- name: Workflow Dispatch | |
if: >- | |
startsWith(github.event_name, 'pull_request') && | |
steps.prepare.outputs.files != '' | |
uses: benc-uk/[email protected] | |
continue-on-error: true # this might error if the workflow is not found, but we still want to run the next job | |
with: | |
ref: ${{ github.base_ref || github.ref_name }} # base ref for PR and branch name for push | |
workflow: dispatcher.yml | |
inputs: ${{ steps.inputs.outputs.primary_inputs }} | |
token: ${{ github.token }} | |
outputs: | |
destination: ${{ steps.prepare.outputs.destination }} | |
target: ${{ steps.prepare.outputs.target }} | |
files: ${{ steps.prepare.outputs.files }} | |
reports_markdown: ${{ steps.prepare.outputs.reports_markdown }} | |
matrix: ${{ steps.prepare.outputs.matrix }} | |
qodana: | |
if: ${{ needs.qodana_initial_check.outputs.files != '' }} | |
needs: [qodana_initial_check] | |
runs-on: ubuntu-latest | |
strategy: | |
fail-fast: false | |
matrix: ${{ fromJson(needs.qodana_initial_check.outputs.matrix) }} | |
name: Qodana-Scan-${{ matrix.language }} | |
continue-on-error: true | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
submodules: recursive | |
- name: Get baseline | |
id: baseline | |
run: | | |
# check if destination is not an integer | |
if ! [[ "${{ needs.qodana_initial_check.outputs.destination }}" =~ ^[0-9]+$ ]] | |
then | |
echo "Running for a branch update" | |
echo "baseline_args=" >> $GITHUB_OUTPUT | |
else | |
echo "Running for a PR" | |
sarif_file=qodana.sarif.json | |
repo=${{ github.event.repository.name }} | |
target=${{ needs.qodana_initial_check.outputs.target }} | |
language=${{ matrix.language }} | |
baseline_file="${repo}/${target}/${language}/results/${sarif_file}" | |
baseline_file_url="https://lizardbyte.github.io/qodana-reports/${baseline_file}" | |
# don't fail if file does not exist | |
wget ${baseline_file_url} || true | |
# check if file exists | |
if [ -f ${sarif_file} ] | |
then | |
echo "baseline exists" | |
echo "baseline_args=--baseline,${sarif_file}" >> $GITHUB_OUTPUT | |
else | |
echo "baseline does not exist" | |
echo "baseline_args=" >> $GITHUB_OUTPUT | |
fi | |
fi | |
- name: Rename Qodana config file | |
id: rename | |
run: | | |
# rename the file | |
if [ "${{ matrix.file }}" != "./qodana.yaml" ] | |
then | |
mv -f ${{ matrix.file }} ./qodana.yaml | |
fi | |
- name: Qodana | |
id: qodana | |
continue-on-error: true # ensure dispatch-qodana job is run | |
uses: JetBrains/[email protected] | |
with: | |
additional-cache-hash: ${{ github.ref }}-${{ matrix.language }} | |
artifact-name: qodana-${{ matrix.language }} # yamllint disable-line rule:line-length | |
args: '--print-problems,${{ steps.baseline.outputs.baseline_args }}' | |
pr-mode: false | |
upload-result: true | |
use-caches: true | |
- name: Set output status | |
id: status | |
run: | | |
# check if qodana failed | |
echo "qodana_status=${{ steps.qodana.outcome }}" >> $GITHUB_OUTPUT | |
outputs: | |
qodana_status: ${{ steps.status.outputs.qodana_status }} | |
dispatch-qodana: | |
# trigger qodana-reports to download artifacts from the matrix runs | |
needs: [qodana_initial_check, qodana] | |
runs-on: ubuntu-latest | |
name: Dispatch Qodana | |
permissions: | |
actions: write # required to use workflow dispatch on fork PRs | |
if: ${{ needs.qodana_initial_check.outputs.files != '' }} | |
steps: | |
- name: Setup qodana publish inputs | |
id: inputs | |
run: | | |
# get the artifacts | |
artifacts=${{ toJson(steps.artifacts.outputs.result) }} | |
artifacts=$(echo $artifacts | jq -c .) | |
# get the target branch | |
target=${{ needs.qodana_initial_check.outputs.target }} | |
# get the destination branch | |
destination=${{ needs.qodana_initial_check.outputs.destination }} | |
# client payload | |
secondary_inputs=$(echo '{ | |
"destination": "'"${destination}"'", | |
"ref": "'"${{ github.ref }}"'", | |
"repo": "'"${{ github.repository }}"'", | |
"repo_name": "'"${{ github.event.repository.name }}"'", | |
"run_id": "'"${{ github.run_id }}"'", | |
"reports_markdown": "'"${{ needs.qodana_initial_check.outputs.reports_markdown }}"'", | |
"status": "'"${{ needs.qodana.outputs.qodana_status }}"'" | |
}' | jq -r .) | |
#escape json control characters | |
secondary_inputs=$(jq -n --arg secondary_inputs "$secondary_inputs" '$secondary_inputs' \ | |
| sed -e 's/\\/\\\\/g' -e 's/"/\\"/g') | |
echo $secondary_inputs | |
primary_inputs=$(echo '{ | |
"dispatch_repository": "'"${{ github.repository_owner }}/qodana-reports"'", | |
"dispatch_workflow": "'"dispatch-qodana.yml"'", | |
"dispatch_ref": "'"master"'", | |
"dispatch_inputs": "'"$secondary_inputs"'" | |
}' | jq -c .) | |
echo $primary_inputs | |
echo $primary_inputs | jq . | |
echo "primary_inputs=$primary_inputs" >> $GITHUB_OUTPUT | |
- name: Workflow Dispatch | |
uses: benc-uk/[email protected] | |
continue-on-error: true # this might error if the workflow is not found, but we don't want to fail the workflow | |
with: | |
ref: ${{ github.base_ref || github.ref_name }} # base ref for PR and branch name for push | |
workflow: dispatcher.yml | |
inputs: ${{ steps.inputs.outputs.primary_inputs }} | |
token: ${{ github.token }} |