Warm Maven Dependency Cache #9
This file contains hidden or 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
| name: Warm Maven Dependency Cache | |
| # This workflow pre-downloads all Maven dependencies via JFrog Artifactory | |
| # and saves them to the GitHub Actions cache. Forked PRs (which cannot | |
| # authenticate to JFrog) restore this cache to build without credentials. | |
| # | |
| # Triggers: | |
| # - push to main when pom.xml changes (keeps cache fresh after dep updates) | |
| # - daily schedule (prevents 7-day cache eviction) | |
| # - manual dispatch (with optional PR number to warm cache for a fork's pom.xml) | |
| on: | |
| push: | |
| branches: [main] | |
| paths: ['**/pom.xml'] | |
| schedule: | |
| - cron: '0 6 * * *' # Daily at 06:00 UTC | |
| workflow_dispatch: | |
| inputs: | |
| pr_number: | |
| description: 'PR number to warm cache for (reads pom.xml from the PR branch). Leave empty to warm from main.' | |
| required: false | |
| type: string | |
| permissions: | |
| id-token: write | |
| contents: read | |
| pull-requests: read # Needed to read PR metadata for fork checkout | |
| jobs: | |
| warm-cache: | |
| # Run on Linux only. Maven repository contents (JARs/POMs) are platform-independent. | |
| # Windows forked PRs restore this same cache via the restore-keys prefix match. | |
| # Note: Windows runners in databricks-protected-runner-group lack bash, which | |
| # is required for the OIDC token exchange scripts. | |
| runs-on: | |
| group: databricks-protected-runner-group | |
| labels: linux-ubuntu-latest | |
| steps: | |
| - name: Set up JDK | |
| uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4 | |
| with: | |
| java-version: 21 | |
| distribution: 'adopt' | |
| # If PR number provided, checkout only pom.xml files from the fork (security: no source code) | |
| - name: Checkout PR pom.xml files (sparse) | |
| if: inputs.pr_number != '' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| # Fetch PR metadata | |
| PR_DATA=$(curl -sLS \ | |
| -H "Accept: application/vnd.github+json" \ | |
| -H "Authorization: Bearer ${{ github.token }}" \ | |
| "https://api.github.com/repos/${{ github.repository }}/pulls/${{ inputs.pr_number }}") | |
| FORK_REPO=$(echo "$PR_DATA" | jq -r '.head.repo.full_name') | |
| FORK_REF=$(echo "$PR_DATA" | jq -r '.head.ref') | |
| echo "Warming cache for PR #${{ inputs.pr_number }} from ${FORK_REPO}@${FORK_REF}" | |
| # Sparse checkout: only pom.xml files (no source code from fork) | |
| git init . | |
| git remote add fork "https://github.com/${FORK_REPO}.git" | |
| git config core.sparseCheckout true | |
| echo "**/pom.xml" > .git/info/sparse-checkout | |
| echo "pom.xml" >> .git/info/sparse-checkout | |
| git fetch --depth=1 fork "${FORK_REF}" | |
| git checkout FETCH_HEAD | |
| - name: Checkout main branch | |
| if: inputs.pr_number == '' | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - name: Get JFrog OIDC token | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| # Get GitHub OIDC ID token | |
| ID_TOKEN=$(curl -sLS \ | |
| -H "User-Agent: actions/oidc-client" \ | |
| -H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ | |
| "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=jfrog-github" | jq .value | tr -d '"') | |
| echo "::add-mask::${ID_TOKEN}" | |
| # Exchange for JFrog access token | |
| ACCESS_TOKEN=$(curl -sLS -XPOST -H "Content-Type: application/json" \ | |
| "https://databricks.jfrog.io/access/api/v1/oidc/token" \ | |
| -d "{\"grant_type\": \"urn:ietf:params:oauth:grant-type:token-exchange\", \"subject_token_type\":\"urn:ietf:params:oauth:token-type:id_token\", \"subject_token\": \"${ID_TOKEN}\", \"provider_name\": \"github-actions\"}" | jq .access_token | tr -d '"') | |
| echo "::add-mask::${ACCESS_TOKEN}" | |
| if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" = "null" ]; then | |
| echo "FAIL: Could not extract JFrog access token" | |
| exit 1 | |
| fi | |
| echo "JFROG_ACCESS_TOKEN=${ACCESS_TOKEN}" >> "$GITHUB_ENV" | |
| echo "JFrog OIDC token obtained successfully" | |
| - name: Configure Maven with JFrog credentials | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| mkdir -p ~/.m2 | |
| cat > ~/.m2/settings.xml << EOF | |
| <settings> | |
| <mirrors> | |
| <mirror> | |
| <id>jfrog-central</id> | |
| <mirrorOf>*</mirrorOf> | |
| <url>https://databricks.jfrog.io/artifactory/db-maven/</url> | |
| </mirror> | |
| </mirrors> | |
| <servers> | |
| <server> | |
| <id>jfrog-central</id> | |
| <username>gha-service-account</username> | |
| <password>${JFROG_ACCESS_TOKEN}</password> | |
| </server> | |
| </servers> | |
| </settings> | |
| EOF | |
| - name: Resolve all dependencies via JFrog | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| # Install all modules — this resolves all external dependencies from JFrog, | |
| # installs inter-module SNAPSHOTs (e.g., jdbc-core used by assembly-thin/uber) | |
| # into ~/.m2/repository, and triggers build-time downloads (spotless formatters, | |
| # annotation processors, etc.). | |
| # | |
| # Note: dependency:resolve cannot be used here because it fails when trying | |
| # to resolve inter-module SNAPSHOTs that don't exist in JFrog. | |
| echo "Installing all modules to populate dependency cache..." | |
| mvn -B install -DskipTests -Dmaven.javadoc.skip=true -Dmaven.source.skip=true -Ddependency-check.skip=true | |
| echo "Dependency resolution complete" | |
| - name: Save Maven dependency cache | |
| uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 | |
| with: | |
| path: ~/.m2/repository | |
| key: maven-deps-${{ hashFiles('**/pom.xml') }} |