diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5f0214d013..6e7cf4d8b5 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -21,7 +21,13 @@ on: - 'main' - 'release/*' - 'support/*' + paths-ignore: + - '.claude/**' + # Safe to filter by path here: no check from this workflow is required in + # .asf.yaml, so a run that never happens blocks nothing. pull_request: + paths-ignore: + - '.claude/**' permissions: # Needed to upload the results to code-scanning dashboard. diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 754dc98e3b..6d1e861123 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -16,6 +16,11 @@ name: Java Maven on: + # Deliberately NOT filtered by path. "Build and Test (JDK 17)" is a required + # status check in .asf.yaml, and a workflow skipped by path filtering never + # reports its checks - they stay Pending and the pull request can never be + # merged. The build job is skipped by condition instead (see `changes` below), + # which does report, as "skipped", and satisfies the requirement. pull_request: push: branches: @@ -23,6 +28,8 @@ on: - 'develop' - 'release/*' - 'support/*' + paths-ignore: + - '.claude/**' workflow_dispatch: workflow_call: @@ -33,8 +40,44 @@ env: LANG: en_US.utf8 jobs: + changes: + name: Detect changes outside .claude + runs-on: ubuntu-latest + outputs: + code: ${{ steps.filter.outputs.code }} + steps: + - name: Check which paths the pull request touches + id: filter + env: + GH_TOKEN: ${{ github.token }} + run: | + set -eu + if [ "${{ github.event_name }}" != "pull_request" ]; then + echo "Not a pull request - building." + echo "code=true" >> "$GITHUB_OUTPUT" + exit 0 + fi + files=$(gh api --paginate \ + "repos/${{ github.repository }}/pulls/${{ github.event.number }}/files" \ + --jq '.[].filename') + echo "Changed files:" + printf '%s\n' "$files" + # Anything outside .claude/ means a real build is needed; an empty + # diff, or one confined to .claude/, does not. Tested by emptiness + # rather than with `grep -qv`, whose exit status is not reliable + # across grep implementations. + outside=$(printf '%s\n' "$files" | grep -vE '^(\.claude/|$)' || true) + if [ -n "$outside" ]; then + echo "code=true" >> "$GITHUB_OUTPUT" + else + echo "Only .claude/ changed - skipping the build." + echo "code=false" >> "$GITHUB_OUTPUT" + fi + build: name: Build and Test (JDK ${{ matrix.java }})${{ matrix.profile == '-Pjakartaee11' && ' (Jakarta EE 11 + Spring 7)' || matrix.profile }} + needs: changes + if: needs.changes.outputs.code == 'true' runs-on: ubuntu-latest strategy: fail-fast: false diff --git a/.github/workflows/owasp.yml b/.github/workflows/owasp.yml index 661b09187a..7b6d0523ae 100644 --- a/.github/workflows/owasp.yml +++ b/.github/workflows/owasp.yml @@ -16,13 +16,19 @@ name: OWASP checkup on: + # Safe to filter by path here: no check from this workflow is required in + # .asf.yaml, so a run that never happens blocks nothing. pull_request: + paths-ignore: + - '.claude/**' push: branches: - 'main' - 'develop' - 'release/*' - 'support/*' + paths-ignore: + - '.claude/**' workflow_dispatch: #Allow manual triggers permissions: read-all diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml index bf33a5520b..becd7c7897 100644 --- a/.github/workflows/sonar.yml +++ b/.github/workflows/sonar.yml @@ -16,10 +16,16 @@ name: SonarCloud on: + # Safe to filter by path here: no check from this workflow is required in + # .asf.yaml, so a run that never happens blocks nothing. pull_request: + paths-ignore: + - '.claude/**' push: branches: - 'main' + paths-ignore: + - '.claude/**' permissions: read-all diff --git a/Jenkinsfile b/Jenkinsfile index 1fce32d7cb..105625d5dd 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -41,9 +41,37 @@ pipeline { cleanWs deleteDirs: true, patterns: [[pattern: '**/target/**', type: 'INCLUDE']] } } + stage('Detect changes') { + steps { + script { + // Skip the build when a push only touched .claude/ - agent + // instructions, not code. Fails open: anything unexpected (no + // previous successful build, an unreachable commit, a git error) + // reports true and the build runs as before. + env.CODE_CHANGED = sh(returnStdout: true, script: ''' + set -u + base="${GIT_PREVIOUS_SUCCESSFUL_COMMIT:-}" + if [ -z "$base" ] || ! git cat-file -e "${base}^{commit}" 2>/dev/null; then + echo true + exit 0 + fi + outside=$(git diff --name-only "$base" HEAD | grep -vE '^(\\.claude/|$)' || true) + if [ -n "$outside" ]; then + echo true + else + echo false + fi + ''').trim() + echo "Changes outside .claude/: ${env.CODE_CHANGED}" + } + } + } } } stage('JDK 21') { + when { + expression { env.CODE_CHANGED != 'false' } + } agent { label 'ubuntu' } @@ -74,6 +102,9 @@ pipeline { } } stage('JDK 17') { + when { + expression { env.CODE_CHANGED != 'false' } + } agent { label 'ubuntu' }