diff --git a/.github/workflows/ci-report.yml b/.github/workflows/ci-report.yml new file mode 100644 index 00000000000..3920750b01f --- /dev/null +++ b/.github/workflows/ci-report.yml @@ -0,0 +1,68 @@ +name: GH Actions CI reporting + +on: + workflow_run: + workflows: [ "GH Actions CI" ] + types: [ completed ] + +defaults: + run: + shell: bash + +env: + MAVEN_ARGS: "-e -B --settings .github/mvn-settings.xml --fail-at-end" + +jobs: + publish-build-scans: + name: Publish Develocity build scans + if: github.repository == 'hibernate/hibernate-search' && github.event.workflow_run.conclusion != 'cancelled' + runs-on: ubuntu-latest + steps: + # Checkout target branch which has trusted code + - name: Check out target branch + uses: actions/checkout@v4 + with: + persist-credentials: false + ref: ${{ github.ref }} + - name: Set up Java ${{ matrix.os.java.version }} + uses: actions/setup-java@v4 + with: + java-version: ${{ matrix.os.java.version }} + distribution: temurin + # https://github.com/actions/cache/blob/main/examples.md#java---maven + - name: Cache local Maven repository + uses: actions/cache@v4 + with: + path: ~/.m2/repository + # use a different key than workflows running untrusted code + key: trusted-${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + trusted-${{ runner.os }}-maven- + - name: Set up Maven + run: ./mvnw -v + - name: Download GitHub Actions artifacts for the Develocity build scans + id: downloadBuildScan + uses: actions/download-artifact@v4 + with: + pattern: build-scan-data-* + github-token: ${{ github.token }} + repository: ${{ github.repository }} + run-id: ${{ github.event.workflow_run.id }} + path: /tmp/downloaded-build-scan-data/ + # Don't fail the build if there are no matching artifacts + continue-on-error: true + - name: Publish Develocity build scans for previous builds + if: ${{ steps.downloadBuildScan.outcome != 'failure'}} + run: | + shopt -s nullglob # Don't run the loop below if there are no artifacts + status=0 + for build_scan_data_directory in /tmp/downloaded-build-scan-data/* + do + rm -rf ~/.m2/.develocity/build-scan-data + mkdir -p ~/.m2/.develocity/build-scan-data + tar -xzf "$build_scan_data_directory/build-scan-data.tgz" -C ~/.m2/.develocity/build-scan-data \ + && ./mvnw $MAVEN_ARGS develocity:build-scan-publish-previous || status=1 + done + exit $status + env: + DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY_PR }} \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/ci.yml similarity index 52% rename from .github/workflows/build.yml rename to .github/workflows/ci.yml index 94d93d6884d..cd691963ea3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ # See https://docs.github.com/en/actions # for more information about GitHub actions. -name: GitHub Actions Build +name: GH Actions CI on: push: @@ -24,9 +24,7 @@ on: - '!wip/**/dependency-update/**' tags: - '**' - # WARNING: Using pull_request_target to access secrets, but we check out the merge commit. - # See checkout action for details. - pull_request_target: + pull_request: types: [opened, synchronize, reopened, ready_for_review] branches: # Pattern order matters: the last matching inclusion/exclusion wins @@ -44,7 +42,7 @@ on: concurrency: group: "workflow = ${{ github.workflow }}, ref = ${{ github.event.ref }}, pr = ${{ github.event.pull_request.id }}" - cancel-in-progress: ${{ github.event_name == 'pull_request_target' || github.repository != 'hibernate/hibernate-search' }} + cancel-in-progress: ${{ github.event_name == 'pull_request' || github.repository != 'hibernate/hibernate-search' }} defaults: run: @@ -90,21 +88,9 @@ jobs: - name: Support longpaths on Windows if: "startsWith(matrix.os.runs-on, 'windows')" run: git config --global core.longpaths true - - name: Check out commit already pushed to branch - if: "! github.event.pull_request.number" - uses: actions/checkout@v4 - - name: Check out PR head - uses: actions/checkout@v4 - if: github.event.pull_request.number + - uses: actions/checkout@v4 with: - # WARNING: This is potentially dangerous since we're checking out unreviewed code, - # and since we're using the pull_request_target event we can use secrets. - # Thus, we must be extra careful to never expose secrets to steps that execute this code, - # and to strictly limit our of secrets to those that only pose minor security threads. - # This means in particular we won't expose Develocity credentials to the main maven executions, - # but instead will execute maven a third time just to push build scans to Develocity; - # see below. - ref: "refs/pull/${{ github.event.pull_request.number }}/head" + persist-credentials: false # Fetch the whole history to make sure that gitflow incremental builder # can find the base commit. fetch-depth: 0 @@ -118,9 +104,10 @@ jobs: uses: actions/cache@v4 with: path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + # use a different key than workflows running in trusted mode + key: ${{ github.event_name == 'push' && 'trusted' || 'untrusted' }}-${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} restore-keys: | - ${{ runner.os }}-maven- + ${{ github.event_name == 'push' && 'trusted' || 'untrusted' }}-${{ runner.os }}-maven- - name: Set up Maven run: ./mvnw -v - name: Docker cleanup @@ -131,17 +118,19 @@ jobs: ./mvnw $MAVEN_ARGS ${{ matrix.os.maven.args }} clean install \ -Pjqassistant -Pdist -Pci-build -DskipITs env: - # WARNING: exposes secrets, so must only be passed to a step that doesn't run unapproved code. - DEVELOCITY_ACCESS_KEY: "${{ github.event_name == 'push' && secrets.GRADLE_ENTERPRISE_ACCESS_KEY || '' }}" - - name: Publish Develocity build scan for previous build (pull request) - # Don't fail a build if publishing fails - continue-on-error: true - if: "${{ !cancelled() && github.event_name == 'pull_request_target' && github.repository == 'hibernate/hibernate-search' }}" - run: | - ./mvnw $MAVEN_ARGS develocity:build-scan-publish-previous - env: - # WARNING: exposes secrets, so must only be passed to a step that doesn't run unapproved code. - DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY_PR }} + DEVELOCITY_ACCESS_KEY: "${{ secrets.DEVELOCITY_ACCESS_KEY || '' }}" + # For jobs running on 'pull_request', tar and upload build scan data. + # The actual publishing must be done in a separate job (see ci-report.yml). + # We don't write to the remote cache as that would be unsafe. + - name: Tar build scan content pushed to subsequent jobs + if: "${{ github.event_name == 'pull_request' && !cancelled() }}" + run: tar -czf build-scan-data.tgz -C ~/.m2/.develocity/build-scan-data . + - name: Upload GitHub Actions artifact for the Develocity build scan + uses: actions/upload-artifact@v4 + if: "${{ github.event_name == 'pull_request' && !cancelled() }}" + with: + name: build-scan-data-initial-${{ matrix.os.name }} + path: build-scan-data.tgz - name: Run integration tests in the default environment run: | @@ -149,37 +138,19 @@ jobs: -Pskip-checks \ ${{ github.event.pull_request.base.ref && format('-Dincremental -Dgib.referenceBranch=refs/remotes/origin/{0}', github.event.pull_request.base.ref) || '' }} env: - # WARNING: exposes secrets, so must only be passed to a step that doesn't run unapproved code. - DEVELOCITY_ACCESS_KEY: "${{ github.event_name == 'push' && secrets.GRADLE_ENTERPRISE_ACCESS_KEY || '' }}" - - name: Publish Develocity build scan for previous build (pull request) - # Don't fail a build if publishing fails - continue-on-error: true - if: "${{ !cancelled() && github.event_name == 'pull_request_target' && github.repository == 'hibernate/hibernate-search' }}" - run: | - ./mvnw $MAVEN_ARGS develocity:build-scan-publish-previous - env: - # WARNING: exposes secrets, so must only be passed to a step that doesn't run unapproved code. - DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY_PR }} + DEVELOCITY_ACCESS_KEY: "${{ secrets.DEVELOCITY_ACCESS_KEY || '' }}" + # Same as above, but for the build scan of the latest Maven run. + - name: Tar build scan content pushed to subsequent jobs + if: "${{ github.event_name == 'pull_request' && !cancelled() }}" + run: tar -czf build-scan-data.tgz -C ~/.m2/.develocity/build-scan-data . + - name: Upload GitHub Actions artifact for the Develocity build scan + uses: actions/upload-artifact@v4 + if: "${{ github.event_name == 'pull_request' && !cancelled() }}" + with: + name: build-scan-data-integrationtest-${{ matrix.os.name }} + path: build-scan-data.tgz - name: Docker cleanup run: ./ci/docker-cleanup.sh - name: Omit produced artifacts from build cache run: rm -r ~/.m2/repository/org/hibernate/search - # Workaround for https://github.com/actions/upload-artifact/issues/240 - - name: List build reports to upload (if build failed) - if: ${{ failure() || cancelled() }} - # The weird syntax is because we're setting a multiline environment variable - # See https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#example-of-a-multiline-string - run: | - { - echo 'buildReportPaths<> "$GITHUB_ENV" - - name: Upload build reports (if build failed) - uses: actions/upload-artifact@v4 - if: ${{ failure() || cancelled() }} - with: - name: ${{ format('build-reports-{0}', matrix.os.name ) }} - path: ${{ env.buildReportPaths }} - retention-days: 7