Skip to content

Performance benchmarks: measurement scripts and analysis docs (#272) … #612

Performance benchmarks: measurement scripts and analysis docs (#272) …

Performance benchmarks: measurement scripts and analysis docs (#272) … #612

Workflow file for this run

# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Java CI with Maven
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
types: [opened, synchronize, reopened]
workflow_dispatch:
# Cancel superseded runs for the same ref to save runner minutes.
concurrency:
group: maven-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 20
# Least privilege: read the repository (checkout + build) and write
# check-run output (test/analysis results). No step uses the workflow
# token to write to pull requests.
permissions:
contents: read
checks: write
# Expose secret-backed tokens as env so steps can be gated on their
# availability. On fork/Dependabot PRs secrets are withheld and resolve to
# an empty string, so the dependent steps are skipped rather than failing.
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0 # Shallow clones should be disabled for better SonarCloud analysis
- name: Set up JDK 17
uses: actions/setup-java@dd06d9cba3e5552c54d9f8ea23572deb30010f7c # v6.0.0
with:
java-version: '17'
distribution: 'zulu'
cache: maven
- name: Cache SonarCloud packages
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ~/.sonar/cache
# Content-addressed so the cache rotates when project config changes,
# with a prefix fallback for warm restores.
key: ${{ runner.os }}-sonar-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-sonar-
- name: Cache Maven packages
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: Build with Maven
run: mvn -B install -Pmetrics --file pom.xml
- name: Verify committed generated example builders
if: github.event_name == 'pull_request'
run: |
# Regenerate the example builders from a clean slate into their tracked
# directory. Deleting first means a *missing* builder (generator
# regression) shows up as a git deletion, stale output as a
# modification, and a brand-new builder as an untracked file — so any
# drift fails the check. (Dependencies were installed by the build step
# above, so -pl example is sufficient here.)
rm -rf example/generated-example-builder
mvn -B -q -DskipTests -pl example clean compile
CHANGES="$(git status --porcelain -- example/generated-example-builder)"
if [ -n "$CHANGES" ]; then
echo "::error::Committed generated example builders are out of date or missing."
echo "Run 'mvn -pl example clean compile' and commit example/generated-example-builder/."
echo "$CHANGES"
git --no-pager diff -- example/generated-example-builder
exit 1
fi
echo "Committed generated example builders are up to date."
- name: Package Sonar analysis inputs (fork PRs)
if: always() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository
env:
# Pass PR metadata through the environment (never interpolate the
# attacker-controlled head ref/sha directly into the shell script).
PR_NUMBER: ${{ github.event.number }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PR_HEAD_REF: ${{ github.event.pull_request.head.ref }}
PR_BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
mkdir -p sonar-analysis-data
cp -a core/target/classes sonar-analysis-data/core-classes 2>/dev/null || true
cp -a processor/target/classes sonar-analysis-data/processor-classes 2>/dev/null || true
cp -a processor/target/site/jacoco-aggregate/jacoco.xml sonar-analysis-data/jacoco-aggregate.xml 2>/dev/null || true
cp -a processor/target/site/jacoco/jacoco.xml sonar-analysis-data/processor-jacoco.xml 2>/dev/null || true
{
printf 'pr_number=%s\n' "$PR_NUMBER"
printf 'pr_head_sha=%s\n' "$PR_HEAD_SHA"
printf 'pr_head_ref=%s\n' "$PR_HEAD_REF"
printf 'pr_base_ref=%s\n' "$PR_BASE_REF"
} > sonar-analysis-data/pr-event.env
- name: Upload Sonar analysis inputs (fork PRs)
if: always() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: sonar-analysis-inputs
path: sonar-analysis-data/
if-no-files-found: warn
- name: SonarCloud Analysis
# Skip when SONAR_TOKEN is unavailable (fork PRs) and for any bot-authored
# PR (Dependabot, Renovate, ...). The bot check uses the PR author's
# account type rather than a hard-coded login, and is not defeated by a
# maintainer re-run (which would otherwise make the withheld token appear).
if: env.SONAR_TOKEN != '' && github.event.pull_request.user.type != 'Bot'
run: mvn -B org.sonarsource.scanner.maven:sonar-maven-plugin:sonar --file pom.xml
- name: Upload JaCoCo HTML report (processor)
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: jacoco-report-html-processor
path: processor/target/site/jacoco/
if-no-files-found: warn
- name: Upload JaCoCo XML report (processor)
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: jacoco-report-xml-processor
path: processor/target/site/jacoco/jacoco.xml
if-no-files-found: warn
# For PRs from forks, secrets are withheld so the direct Codecov steps
# below are skipped. Instead publish the coverage data (plus the PR
# identity) as an artifact; the privileged fork-coverage.yml workflow
# (triggered on workflow_run, in the base-repo context) consumes it and
# uploads to Codecov without ever executing fork code.
- name: Assemble Codecov payload (fork PRs)
if: always() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository
env:
# Pass PR metadata through the environment (never interpolate the
# attacker-controlled head ref/sha directly into the shell script).
PR_NUMBER: ${{ github.event.number }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PR_HEAD_REF: ${{ github.event.pull_request.head.ref }}
run: |
mkdir -p codecov-payload/surefire codecov-payload/failsafe
cp -f processor/target/site/jacoco/jacoco.xml codecov-payload/ 2>/dev/null || true
cp -f processor/target/site/jacoco-aggregate/jacoco.xml codecov-payload/jacoco-aggregate.xml 2>/dev/null || true
cp -f processor/target/surefire-reports/*.xml codecov-payload/surefire/ 2>/dev/null || true
cp -f processor/target/failsafe-reports/*.xml codecov-payload/failsafe/ 2>/dev/null || true
{
printf 'pr_number=%s\n' "$PR_NUMBER"
printf 'pr_head_sha=%s\n' "$PR_HEAD_SHA"
printf 'pr_head_ref=%s\n' "$PR_HEAD_REF"
} > codecov-payload/pr-event.env
- name: Upload Codecov payload artifact (fork PRs)
if: always() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: codecov-payload
path: codecov-payload/
if-no-files-found: warn
- name: Upload test results to Codecov (processor)
# Skip when CODECOV_TOKEN is unavailable (fork PRs) and for any bot-authored PR.
if: always() && env.CODECOV_TOKEN != '' && github.event.pull_request.user.type != 'Bot'
uses: codecov/test-results-action@0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3 # v1.2.1
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: |
processor/target/surefire-reports/*.xml
processor/target/failsafe-reports/*.xml
fail_ci_if_error: true
verbose: false
- name: Upload coverage to Codecov (processor + core via aggregate)
# Skip when CODECOV_TOKEN is unavailable (fork PRs) and for any bot-authored PR.
if: always() && env.CODECOV_TOKEN != '' && github.event.pull_request.user.type != 'Bot'
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with:
fail_ci_if_error: true
files: |
processor/target/site/jacoco/jacoco.xml
processor/target/site/jacoco-aggregate/jacoco.xml
flags: processor
name: codecov-upload
verbose: false
token: ${{ secrets.CODECOV_TOKEN }}