Skip to content

Release Thin JAR

Release Thin JAR #31

Workflow file for this run

# 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