Skip to content

Maven CICD Pipeline #8998

Maven CICD Pipeline

Maven CICD Pipeline #8998

name: Maven CICD Pipeline
on:
workflow_dispatch:
inputs:
logLevel:
description: 'Log level'
required: true
default: 'warning'
tags:
description: 'Tags'
required: false
push:
branches:
- master
- release-*
pull_request:
merge_group:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref || github.run_id }}
# Cancel any in-progress runs for the same branch/PR to prevent delays from changes during build
# On master and other branches run will set as pending. Any new builds requested will replace the pending build
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
JVM_TEST_MAVEN_OPTS: "-e -B --no-transfer-progress -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn"
DOCKER_PLATFORMS: "linux/amd64,linux/arm64"
REGISTRY: ghcr.io
DOCKER_IMAGE: dotcms/dotcms_test
DOCKER_TAG: run-${{ github.run_id }}
jobs:
#
# Detect Code that has changed and create outputs to uses as conditionals
#
changes:
name: Check Changed Files
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
backend: ${{ steps.filter-rewrite.outputs.backend }}
frontend: ${{ steps.filter-rewrite.outputs.frontend }}
build: ${{ steps.filter-rewrite.outputs.build }}
jvm_unit_test: ${{ steps.filter-rewrite.outputs.jvm_unit_test }}
cli: ${{ steps.filter-rewrite.outputs.cli }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3.0.1
id: filter
with:
filters: .github/filters.yaml
list-files: 'escape'
- name: Rewrite Filter
id: filter-rewrite
env:
CICD_SKIP_TESTS: ${{ vars.CICD_SKIP_TESTS }}
run: |
# Default action outcomes based on paths-filter action outputs
frontend=${{ steps.filter.outputs.frontend }}
cli=${{ steps.filter.outputs.cli }}
backend=${{ steps.filter.outputs.backend }}
build=${{ steps.filter.outputs.build }}
jvm_unit_test=${{ steps.filter.outputs.jvm_unit_test }}
# Check if the commit is to the master branch
is_master=$(echo ${{ github.ref }} | sed -n 's/refs\/heads\/master/&/p')
skip_tests=${CICD_SKIP_TESTS:-false} # Use environment variable, default to 'false'
# Adjust outputs based on conditions
if [ "$is_master" == "refs/heads/master" ]; then
echo "Running build and all tests on the master branch."
build=true
frontend=true
cli=true
backend=true
jvm_unit_test=true
fi
# The below line ensures that if skip_tests is true, all tests are set to false.
if [ "$skip_tests" == "true" ]; then
echo "Skipping tests as per CICD_SKIP_TESTS flag."
frontend=false
cli=false
backend=false
jvm_unit_test=false
fi
# Export the outcomes as GitHub Actions outputs
echo "frontend=${frontend}" >> $GITHUB_OUTPUT
echo "cli=${cli}" >> $GITHUB_OUTPUT
echo "backend=${backend}" >> $GITHUB_OUTPUT
echo "build=${build}" >> $GITHUB_OUTPUT
echo "jvm_unit_test=${jvm_unit_test}" >> $GITHUB_OUTPUT
#
# Initial JDK 11 Build
# Basic build and install all with maven without running tests.
# Provides local maven repo for subsequent steps
#
build-jdk11:
name: "Initial JDK 11 Build"
runs-on: ubuntu-20.04
needs: changes
if: ${{ needs.changes.outputs.build == 'true' }}
env:
DOCKER_BUILD_CONTEXT: /home/runner/work/_temp/core-build
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup master branch locally without switching current branch
if: github.ref != 'refs/heads/master'
run: git fetch origin master:master
- uses: ./.github/actions/cleanup-runner
- name: Set up JDK 11
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'temurin'
- name: Get Date
id: get-date
run: |
echo "date=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT
shell: bash
- name: Cache Maven Repository
id: cache-maven
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: mavencore-${{ steps.get-date.outputs.date }}-${{ github.run_id }}
restore-keys: |
mavencore-${{ steps.get-date.outputs.date }}
- name: Cache Node Binary
id: cache-node-binary
uses: actions/cache@v4
with:
path: |
installs
key: node-binary-${{ hashFiles('core-web/.nvmrc') }}
- name: Cache yarn
id: cache-yarn
uses: actions/cache@v4
with:
path: |
~/.cache/yarn
# if specific cache does not exist then can base upon latest version
key: yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: yarn-
- name: Lint Checks
shell: bash
run: |
./mvnw $JVM_TEST_MAVEN_OPTS -Pvalidate --fail-at-end -Dgithub.event.name=${{ github.event_name }} --file pom.xml
- name: Maven Build No Test
shell: bash
run: |
echo "Creating $DOCKER_BUILD_CONTEXT"
mkdir -p $DOCKER_BUILD_CONTEXT
./mvnw -Dprod=true $JVM_TEST_MAVEN_OPTS -Dcoreit.test.skip=true -Dpostman.test.skip=true -Ddocker.buildArchiveOnly=$DOCKER_BUILD_CONTEXT -Ddotcms.image.name=${DOCKER_IMAGE}:${DOCKER_TAG} --show-version -DskipTests=true -DskipITs=true clean install --file pom.xml
- name: Persist Maven Repo
uses: actions/upload-artifact@v4
with:
name: maven-repo
path: ~/.m2/repository
- name: Delete Local Artifacts From Cache
shell: bash
run: find ~/.m2 -name \*-SNAPSHOT -type d -exec rm -rf {} +
- name: Persist Docker Build Context
uses: actions/upload-artifact@v4
with:
name: docker-build-context
path: ${{ env.DOCKER_BUILD_CONTEXT }}/docker-build.tar
- name: Save Docker image to a tar file
run: docker save ${{ env.DOCKER_IMAGE }}:${{ env.DOCKER_TAG }} > image.tar
- name: Upload Docker image as artifact
uses: actions/upload-artifact@v4
with:
name: docker-image
path: image.tar
- name: Core Build Report
uses: actions/upload-artifact@v4
if: always() && !cancelled()
with:
name: "build-reports-Initial JDK 11 Build"
path: |
target/build-reports.json
LICENSE
retention-days: 2
#
# Run all JVM Unit Tests in parallel with other tests
#
linux-jvm-tests:
name: JVM Unit Tests - JDK ${{matrix.java.name}}
runs-on: ubuntu-20.04
if: ${{ needs.changes.outputs.jvm_unit_test == 'true' }}
needs: [changes,build-jdk11]
timeout-minutes: 240
env:
MAVEN_OPTS: -Xmx2048m
strategy:
fail-fast: false
matrix:
java: [ { name: "11", java-version: 11, distribution: 'temurin', maven_args: "" } ]
steps:
- uses: actions/checkout@v4
- name: Set up JDK ${{ matrix.java.name }}
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java.java-version }}
distribution: ${{ matrix.java.distribution }}
- name: Get Date
id: get-date
run: |
echo "date=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT
shell: bash
- name: Download Maven Repo
uses: actions/download-artifact@v4
with:
name: maven-repo
path: ~/.m2/repository
- name: Build
# exclude core web we aare testing that separately
run: eval ./mvnw -Pcoverage -Dprod $JVM_TEST_MAVEN_OPTS test -pl \!:dotcms-core-web ${{ matrix.java.maven_args}}
- name: Prepare reports archive (if maven failed)
if: failure()
shell: bash
run: find . -name '*-reports' -type d | tar -czf test-reports.tgz -T -
- name: Upload reports Archive (if maven failed)
uses: actions/upload-artifact@v4
if: failure()
with:
name: test-reports-linux-jvm${{matrix.java.name}}
path: 'test-reports.tgz'
- name: core-maven-unit-tests
uses: actions/upload-artifact@v3
if: always()
with:
name: "build-reports-test-JVM Tests - JDK ${{matrix.java.name}}"
path: |
dotCMS/target/*-reports/TEST-*.xml
dotCMS/target/jacoco-report/*.exec
target/build-report.json
LICENSE
retention-days: 2
linux-cli-tests:
name: CLI Tests - JDK ${{matrix.java.name}}
runs-on: ubuntu-20.04
if: ${{ needs.changes.outputs.cli == 'true' || needs.changes.outputs.backend == 'true' }}
needs: [ changes, build-jdk11 ]
timeout-minutes: 240
env:
MAVEN_OPTS: -Xmx2048m
strategy:
fail-fast: true
matrix:
java: [ { name: "11", java-version: 11, distribution: 'temurin', maven_args: "" } ]
steps:
- uses: actions/checkout@v4
- name: Set up JDK ${{ matrix.java.name }}
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java.java-version }}
distribution: ${{ matrix.java.distribution }}
- name: Download Docker image artifact
uses: actions/download-artifact@v4
with:
name: docker-image
path: /tmp/docker-image
- name: Load Docker image from tar file
run: docker load < /tmp/docker-image/image.tar
- name: Get Date
id: get-date
run: |
echo "date=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT
shell: bash
- name: Download Maven Repo
uses: actions/download-artifact@v4
with:
name: maven-repo
path: ~/.m2/repository
- id: prepare-license
name: Prepare license
env:
DOTCMS_LICENSE_KEY: ${{ secrets.DOTCMS_LICENSE }}
run: |
DOTCMS_LICENSE_PATH=~/.dotcms/license
mkdir -p ${DOTCMS_LICENSE_PATH}
echo "${DOTCMS_LICENSE_KEY}" > ${DOTCMS_LICENSE_PATH}/license.dat
echo "DOTCMS_LICENSE_FILE=${DOTCMS_LICENSE_PATH}/license.dat" >> "$GITHUB_ENV"
- name: Build
run: eval ./mvnw -Dprod $JVM_TEST_MAVEN_OPTS -Dtestcontainers.docker.image=${DOCKER_IMAGE}:${DOCKER_TAG} -pl :dotcms-api-data-model,:dotcms-cli verify ${{ matrix.java.maven_args}}
- name: Prepare reports archive (if maven failed)
if: failure()
shell: bash
run: find . -name '*-reports' -type d | tar -czf test-reports.tgz -T -
- name: Upload reports Archive (if maven failed)
uses: actions/upload-artifact@v4
if: failure()
with:
name: test-reports-cli-jvm${{matrix.java.name}}
path: 'test-reports.tgz'
- name: cli-tests
uses: actions/upload-artifact@v3
if: always()
with:
name: "build-reports-test-cli - JDK ${{matrix.java.name}}"
path: |
tools/dotcms-cli/**/target/failsafe-reports/*.xml
tools/dotcms-cli/**/target/jacoco-report/*.exec
target/build-report.json
LICENSE
retention-days: 2
#
# Run Frontend Tests
#
linux-frontend-tests:
name: Frontend Unit Tests
runs-on: ubuntu-20.04
if: ${{ needs.changes.outputs.frontend == 'true' }}
needs: [changes,build-jdk11]
timeout-minutes: 240
env:
MAVEN_OPTS: -Xmx2048m
steps:
- uses: actions/checkout@v4
- name: Set up JDK 11
uses: actions/setup-java@v4
with:
java-version: 11
distribution: 'temurin'
- name: Get Date
id: get-date
run: |
echo "date=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT
shell: bash
- name: Download Maven Repo
uses: actions/download-artifact@v4
with:
name: maven-repo
path: ~/.m2/repository
continue-on-error: true
- name: Restore Node Binary
id: cache-node-binary
uses: actions/cache/restore@v4
with:
path: |
installs
key: node-binary-${{ hashFiles('core-web/.nvmrc') }}
- name: Cache yarn
id: cache-yarn
uses: actions/cache@v4
with:
path: |
~/.cache/yarn
# if specific cache does not exist then can base upon latest version
key: yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: yarn-
- name: Build # expect node cache to exist from
shell: bash
run: eval ./mvnw -Dprod $JVM_TEST_MAVEN_OPTS -pl :dotcms-core-web test
- name: Prepare failure archive (if maven failed)
if: failure()
shell: bash
run: find . -name 'surefire-reports' -type d | tar -czf test-reports.tgz -T -
- name: Upload failure Archive (if maven failed)
uses: actions/upload-artifact@v4
if: failure()
with:
name: test-reports-frontend
path: 'test-reports.tgz'
- name: frontend-unit-tests
uses: actions/upload-artifact@v3
if: always()
with:
name: "build-reports-test-Frontend unit tests"
path: |
core-web/target/*-reports/**/TEST-*.xml
target/build-report.json
LICENSE
retention-days: 2
#
# Run Legacy Integration test suite batches
#
linux-integration-tests:
name: JVM IT Tests - JDK ${{matrix.java.name}} ${{matrix.suites.name}}
runs-on: ubuntu-20.04
# Skip master in forks
if: ${{ needs.changes.outputs.backend == 'true' }}
needs: [build-jdk11,changes]
timeout-minutes: 240
env:
MAVEN_OPTS: -Xmx2048m
strategy:
fail-fast: false
matrix:
java: [ { name: "11", java-version: 11, distribution: 'temurin', maven_args: "" } ]
suites:
- { name: "MainSuite 1a", pathName: "mainsuite1a", maven_args: '-Dit.test=MainSuite1a -Dit.test.forkcount=1' }
- { name: "MainSuite 1b", pathName: "mainsuite1b", maven_args: '-Dit.test=MainSuite1b -Dit.test.forkcount=1' }
- { name: "MainSuite 2a", pathName: "mainsuite2a", maven_args: '-Dit.test=MainSuite2a -Dit.test.forkcount=1' }
- { name: "MainSuite 2b", pathName: "mainsuite2b", maven_args: '-Dit.test=MainSuite2b -Dit.test.forkcount=1' }
steps:
- uses: actions/checkout@v4
- name: Set up IT Tests ${{ matrix.java.name }} ${{ matrix.suites.name }}
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java.java-version }}
distribution: ${{ matrix.java.distribution }}
#- name: Download Maven Repo
# uses: actions/download-artifact@v4
# with:
# name: maven-repo
# path: .
#- name: Extract Maven Repo
# shell: bash
# run: tar -xzf maven-repo.tgz -C ~
- name: Get Date
id: get-date
run: |
echo "date=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT
shell: bash
- name: Download Maven Repo
uses: actions/download-artifact@v4
with:
name: maven-repo
path: ~/.m2/repository
- name: Build
env:
DOT_DOTCMS_LICENSE: ${{ secrets.DOTCMS_LICENSE }}
run: eval ./mvnw -Pcoverage -Dprod $JVM_TEST_MAVEN_OPTS verify -pl :dotcms-integration -Dcoreit.test.skip=false ${{ matrix.suites.maven_args}} ${{ matrix.java.maven_args}}
- name: Prepare reports archive (if maven failed)
if: failure()
shell: bash
run: find . -name '*-reports' -type d | tar -czf test-reports.tgz -T -
- name: Upload failure Archive (if maven failed)
uses: actions/upload-artifact@v4
if: failure()
with:
name: test-reports-linux-jvm${{matrix.java.name}}-${{matrix.suites.pathName}}
path: 'test-reports.tgz'
- name: failsafe-it-tests # Uploads will be merged with same name
uses: actions/upload-artifact@v3
if: always()
with:
name: "build-reports-test-IT Tests - JDK ${{matrix.java.name}} - ${{matrix.suites.name}}"
path: |
dotcms-integration/target/failsafe-reports/*.xml
dotcms-integration/target/jacoco-report/*.exec
target/build-report.json
LICENSE
retention-days: 2
linux-postman-tests:
name: Run Postman Tests - ${{matrix.collection_group}}
runs-on: ubuntu-latest
needs: [build-jdk11, changes]
if: ${{ needs.changes.outputs.backend == 'true' }}
strategy:
fail-fast: false
matrix:
collection_group: [ 'category-content', 'container', 'experiment', 'graphql', 'page', 'pp', 'template', 'workflow', 'default' ]
steps:
- uses: actions/checkout@v4
- id: fetch-core
name: Fetch Core Repo
uses: actions/checkout@v4
- name: Download Maven Repo
uses: actions/download-artifact@v4
with:
name: maven-repo
path: ~/.m2/repository
- name: Download Docker image artifact
uses: actions/download-artifact@v4
with:
name: docker-image
path: /tmp/docker-image
- name: Load Docker image from tar file
run: docker load < /tmp/docker-image/image.tar
- name: Cache Node Binary
id: cache-node-binary
uses: actions/cache@v4
with:
path: |
installs
key: node-binary-${{ hashFiles('core-web/.nvmrc') }}
- name: Cache yarn
id: cache-yarn
uses: actions/cache@v4
with:
path: |
~/.cache/yarn
# if specific cache does not exist then can base upon latest version
key: yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: yarn-
- name: Prepare license
run: |
mkdir -p ~/.dotcms/license/
touch ~/.dotcms/license/license.dat
echo "${{ secrets.DOTCMS_LICENSE }}" > ~/.dotcms/license/license.dat
- id: run-postman-tests
name: Run Postman Tests
timeout-minutes: 90
run: |
./mvnw -Pcoverage $JVM_TEST_MAVEN_OPTS verify \
-pl :dotcms-postman -Dpostman.test.skip=false \
-Dpostman.collections=${{ matrix.collection_group }} \
-Ddotcms.image.name=${DOCKER_IMAGE}:${DOCKER_TAG}
pec=$?
[[ pec -eq 0 ]] || exit pec
- name: Prepare reports archive (if maven failed)
if: failure()
shell: bash
run: |
find . -name '*-reports' -type d
tree ./dotcms-postman
find . -name '*-reports' -type d | tar -czf test-reports.tgz -T -
- name: Upload failure Archive (if maven failed)
uses: actions/upload-artifact@v4
if: failure()
with:
name: test-reports-postman-${{ matrix.collection_group }}
path: 'test-reports.tgz'
- name: failsafe-postman-tests # Uploads will be merged with same name
uses: actions/upload-artifact@v3
if: always()
with:
name: "build-reports-test-postman - ${{ matrix.collection_group }}"
path: |
dotcms-postman/target/failsafe-reports/*.xml
dotcms-postman/target/jacoco-report/*.exec
target/build-report.json
LICENSE
retention-days: 2
#
# Run CLI build artifacts
#
build-cli:
name: CLI Build
needs: [build-jdk11,linux-jvm-tests,linux-integration-tests,linux-postman-tests]
uses: ./.github/workflows/cli-build-artifacts.yml
with:
buildNativeImage: true
branch: ${{ github.ref }}
sonarqube:
name: SonarQube Scan
runs-on: ubuntu-latest
needs: [build-jdk11,linux-jvm-tests,linux-integration-tests,linux-postman-tests,linux-frontend-tests,linux-cli-tests]
if: |
(always() && !cancelled()) &&
(needs.changes.outputs.build == 'true') &&
(github.repository == 'dotCMS/core') &&
(github.ref == 'refs/heads/master' || github.event_name == 'pull_request')
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup master branch locally without switching current branch
if: github.ref != 'refs/heads/master'
run: git fetch origin master:master
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'temurin'
- name: Get Date
id: get-date
run: |
echo "date=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT
shell: bash
- name: Download Maven Repo
uses: actions/download-artifact@v4
with:
name: maven-repo
path: ~/.m2/repository
continue-on-error: true
- name: Cache SonarQube packages
uses: actions/cache@v4
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
# download the coverage execution files
- name: Download build reports
id: download-artifact
uses: dawidd6/action-download-artifact@v3.0.0
with:
name: build-reports-test-.*
name_is_regexp: true
path: dotcms-core/target/build-reports
if_no_artifact_found: warn
- name: Maven Build No Test
env:
MAVEN_OPTS: "-Xmx2048m"
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
shell: bash
run: |
./mvnw $JVM_TEST_MAVEN_OPTS compile -DskipTests=true -Pcoverage -Dcoverage.report.phase=compile
./mvnw $JVM_TEST_MAVEN_OPTS -Dsonar.log.level=DEBUG org.sonarsource.scanner.maven:sonar-maven-plugin:sonar '-Dcoverage.execution.locations=build-reports/**/*.exec' -Dsonar.projectKey=dotCMS_core_AYSbIemxK43eThAXTlt- -Dsonar.host.url=${SONAR_HOST_URL} -Dsonar.token=$SONAR_TOKEN
- name: SonarQube Quality Gate check
id: sonarqube-quality-gate-check
uses: sonarsource/sonarqube-quality-gate-action@master
continue-on-error: false
# Force to fail step after specific time.
timeout-minutes: 10
with:
scanMetadataReportFile: target/sonar/report-task.txt
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
MAVEN_OPTS: "-Xmx2048m"
- name: "Example show SonarQube Quality Gate Status value"
run: echo "The Quality Gate status is ${{ steps.sonarqube-quality-gate-check.outputs.quality-gate-status }}"
#
# Collate reports and build status
#
prepare-report-data:
name: Prepare Report Data
runs-on: ubuntu-20.04
needs: [ build-jdk11,linux-jvm-tests,linux-integration-tests,linux-frontend-tests,linux-cli-tests,linux-postman-tests,sonarqube,build-cli ]
if: always()
outputs:
aggregate_status: ${{ steps.prepare-workflow-data.outputs.aggregate_status }}
steps:
- name: Download build reports
id: download-artifact
uses: dawidd6/action-download-artifact@v3.0.0
with:
name: "build-reports-*"
name_is_regexp: true
path: /tmp/build-step-reports
if_no_artifact_found: warn
- name: Prepare workflow data
id: prepare-workflow-data
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
AGGREGATE_STATUS="SUCCESS"
jobs_status="${{ toJson(needs) }}"
echo "job status=${jobs_status}"
while IFS=" " read -r key result; do
key=$(echo $key | tr -d ' {')
result=$(echo $result | tr -d ',')
echo "Job: $key, Result: $result"
if [[ $result == "cancelled" ]]; then
AGGREGATE_STATUS="CANCELLED"
break
elif [[ $result == "failure" ]]; then
AGGREGATE_STATUS="FAILURE"
fi
done < <(echo "$jobs_status" | awk -F': ' '/result:/ {print $1,$2}')
FIRST_FAIL_STEP=""
FIRST_FAIL_MODULE=""
echo '{' > workflow-data.json
EVENT_TYPE="${{ github.event_name }}"
if [[ "$EVENT_TYPE" == "pull_request" ]]; then
echo "Creating workflow data for pull request ${PR_TITLE}"
BRANCH="${{ github.head_ref }}"
else
PR_TITLE="N/A"
BRANCH="${{ github.ref }}"
echo "Creating workflow data for branch ${BRANCH}"
fi
BRANCH="${BRANCH##*/}"
PR_TITLE_JQ=$(jq --arg title "$PR_TITLE" -n '$title')
echo '"branch": "'$BRANCH'",' >> workflow-data.json
echo '"run_id": "'${{ github.run_id }}'",' >> workflow-data.json
echo '"trigger_event_name": "'$GITHUB_EVENT_NAME'",' >> workflow-data.json
echo '"source_repository": "'$GITHUB_REPOSITORY'",' >> workflow-data.json
echo '"merge_sha": "'${{ github.sha }}'",' >> workflow-data.json
echo '"base_sha": "'${{ github.event.pull_request.base.sha }}'",' >> workflow-data.json
echo '"base_branch": "'${{ github.event.pull_request.base.sha }}'",' >> workflow-data.json
echo '"base_author": "'${{ github.event.pull_request.base.user.login }}'",' >> workflow-data.json
echo '"head_author": "'${{ github.event.pull_request.head.user.login }}'",' >> workflow-data.json
echo '"head_name": "'${{ github.event.pull_request.head.ref }}'",' >> workflow-data.json
echo '"head_sha": "'${{ github.event.pull_request.head.sha }}'",' >> workflow-data.json
echo '"pr_id": "'${{ github.event.pull_request.id }}'",' >> workflow-data.json
echo '"pr_number": "'${{ github.event.pull_request.number }}'",' >> workflow-data.json
echo "\"pr_title\": $PR_TITLE_JQ," >> workflow-data.json
echo '"pr_author": "'${{ github.event.pull_request.user.login }}'",' >> workflow-data.json
echo '"pr_merge_state": "'${{ github.event.pull_request.mergeable_state }}'",' >> workflow-data.json
echo '"build_reports": [' >> workflow-data.json
total_reports=$(find /tmp/build-step-reports/build-reports-*/target -name build-report.json 2>/dev/null | wc -l)
report_index=0
if [ "$total_reports" -eq "0" ]; then
echo "No build report files found."
else
for build_report in "/tmp/build-step-reports/build-reports-"*/target/build-report.json; do
((report_index=report_index+1))
step_name=$(basename "$(dirname "$(dirname "$build_report")")" | sed 's/build-reports-//')
cat "$build_report" | jq ".step_name = \"$step_name\"" >> workflow-data.json
# If the aggregate status is still SUCCESS, check if this module failed
if [[ "$AGGREGATE_STATUS" == "SUCCESS" ]]; then
# Loop over each projectReport
length=$(jq '.projectReports | length' "$build_report")
for (( i=0; i<$length; i++ )); do
status=$(jq -r ".projectReports[$i].status" "$build_report")
if [[ "$status" == "FAILURE" ]]; then
AGGREGATE_STATUS="FAILURE"
FIRST_FAIL_STEP="$step_name"
FIRST_FAIL_MODULE="$(jq -r ".projectReports[$i].name" "$build_report")"
FIRST_FAIL_ERROR="$(jq -r ".projectReports[$i].error" "$build_report")"
fi
done
fi
# If not the last file, append a comma
if (( report_index != total_reports )); then
echo ',' >> workflow-data.json
fi
done
fi
echo '],' >> workflow-data.json
echo '"aggregate_status": "'$AGGREGATE_STATUS'"' >> workflow-data.json
if [[ "$AGGREGATE_STATUS" != "SUCCESS" ]]; then
echo ',' >> workflow-data.json
echo '"first_fail_step": "'$FIRST_FAIL_STEP'",' >> workflow-data.json
echo '"first_fail_module": "'$FIRST_FAIL_MODULE'",' >> workflow-data.json
echo '"first_fail_error": "'$FIRST_FAIL_ERROR'"' >> workflow-data.json
fi
echo '}' >> workflow-data.json
echo "aggregate_status=${AGGREGATE_STATUS}" >> $GITHUB_OUTPUT
- name: Upload workflow data
uses: actions/upload-artifact@v3
with:
name: workflow-data
path: ./workflow-data.json
final-status:
name: Final Status
needs: prepare-report-data
if: always()
runs-on: ubuntu-20.04
steps:
- name: Check Final Status
run: |
if [ "${{ needs.prepare-report-data.outputs.aggregate_status }}" != "SUCCESS" ]; then
echo "One or more jobs failed!"
exit 1
fi