Release Thin JAR #31
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
| # TODO(security): When re-enabling this workflow: | |
| # 1. Restore the original 'if:' condition (see comment on publish-thin job) | |
| # 2. Consider adding SLSA provenance via slsa-framework/slsa-github-generator | |
| # 3. Verify release secrets are rotated: GPG_PRIVATE_KEY, MAVEN_CENTRAL_USERNAME, MAVEN_CENTRAL_PASSWORD | |
| name: Release Thin JAR | |
| on: | |
| workflow_run: | |
| workflows: ["Release"] | |
| types: | |
| - completed | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: 'Tag to release (e.g., v3.0.5)' | |
| required: true | |
| type: string | |
| permissions: | |
| id-token: write | |
| contents: write | |
| jobs: | |
| # Gate: Vulnerability scan must pass before publishing. | |
| # Runs OWASP Dependency Check against NVD and fails on CVSS >= 7. | |
| vulnerability-scan: | |
| if: false | |
| runs-on: | |
| group: databricks-protected-runner-group | |
| labels: linux-ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| ref: ${{ github.event_name == 'workflow_dispatch' && format('refs/tags/{0}', inputs.tag) || github.event.workflow_run.head_sha }} | |
| fetch-tags: true | |
| fetch-depth: 0 | |
| - name: Set up JDK | |
| uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4 | |
| with: | |
| java-version: 21 | |
| distribution: 'adopt' | |
| - name: Get JFrog OIDC token | |
| run: | | |
| set -euo pipefail | |
| 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}" | |
| 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" | |
| - name: Configure maven | |
| 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: Run OWASP Dependency Check | |
| run: | | |
| mvn -pl jdbc-core org.owasp:dependency-check-maven:check \ | |
| -Dnvd.api.key=${{ secrets.NVD_API_KEY }} \ | |
| -DfailBuildOnCVSS=7 | |
| - name: Upload scan reports | |
| if: always() | |
| uses: actions/upload-artifact@ea165f8d65b6db9b8a1f7b0951caef032b8f2f72 # v4 | |
| with: | |
| name: release-thin-vulnerability-scan | |
| path: | | |
| jdbc-core/target/dependency-check-report.html | |
| jdbc-core/target/dependency-check-report.json | |
| publish-thin: | |
| # DISABLED: Third-party package publishing frozen per company-wide policy. | |
| # To re-enable, replace 'false' below with the original condition: | |
| # github.event_name == 'workflow_dispatch' || | |
| # (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') | |
| if: false | |
| needs: vulnerability-scan | |
| runs-on: | |
| group: databricks-protected-runner-group | |
| labels: linux-ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| ref: ${{ github.event_name == 'workflow_dispatch' && format('refs/tags/{0}', inputs.tag) || github.event.workflow_run.head_sha }} | |
| fetch-tags: true | |
| fetch-depth: 0 | |
| - name: Set up Java for publishing to Maven Central Repository | |
| uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4 | |
| env: | |
| GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} | |
| with: | |
| java-version: 11 | |
| server-id: central | |
| distribution: "adopt" | |
| server-username: MAVEN_CENTRAL_USERNAME | |
| server-password: MAVEN_CENTRAL_PASSWORD | |
| gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} | |
| gpg-passphrase: GPG_PASSPHRASE | |
| - name: Get JFrog OIDC token | |
| run: | | |
| set -euo pipefail | |
| 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}" | |
| 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 | |
| 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 | |
| echo "Maven configured to use JFrog registry" | |
| - name: Build dependencies | |
| run: | | |
| mvn -Prelease clean install --batch-mode -pl jdbc-core -am -Dgpg.skip=true \ | |
| -Dnvd.api.key=${{ secrets.NVD_API_KEY }} \ | |
| -Dossindex.username=${{ secrets.OSSINDEX_USERNAME }} \ | |
| -Dossindex.password=${{ secrets.OSSINDEX_PASSWORD }} | |
| - name: Publish thin JAR to Maven Central | |
| run: | | |
| mvn -Prelease deploy --batch-mode -pl assembly-thin \ | |
| -Dnvd.api.key=${{ secrets.NVD_API_KEY }} \ | |
| -Dossindex.username=${{ secrets.OSSINDEX_USERNAME }} \ | |
| -Dossindex.password=${{ secrets.OSSINDEX_PASSWORD }} | |
| env: | |
| GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} | |
| MAVEN_CENTRAL_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }} | |
| MAVEN_CENTRAL_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} | |
| - name: Get tag name from commit | |
| id: get_tag | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| TAG="${{ inputs.tag }}" | |
| else | |
| TAG=$(git tag --points-at HEAD | grep "^v" | head -1) | |
| if [ -z "$TAG" ]; then | |
| echo "Error: No tag found for current commit" | |
| exit 1 | |
| fi | |
| fi | |
| echo "tag=$TAG" >> $GITHUB_OUTPUT | |
| echo "Found tag: $TAG" | |
| - name: Verify main release exists | |
| if: github.event_name == 'workflow_run' | |
| uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 | |
| with: | |
| script: | | |
| const tag = '${{ steps.get_tag.outputs.tag }}'; | |
| console.log(`Verifying main release exists for ${tag}`); | |
| try { | |
| await github.rest.repos.getReleaseByTag({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| tag: tag | |
| }); | |
| console.log(`Release found for ${tag}`); | |
| } catch (e) { | |
| core.setFailed(`Main release not found for tag ${tag}: ${e.message}`); | |
| } | |
| - name: Upload Thin JAR to GitHub Release | |
| uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1 | |
| with: | |
| tag_name: ${{ steps.get_tag.outputs.tag }} | |
| files: | | |
| assembly-thin/target/databricks-jdbc-thin-*.jar |