Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c19b91d
fix(ci): pre-bootstrap JFrog pip routing before setup-python
May 18, 2026
facda8f
fix(security): drop unknown failNoKey param on pgpverify 1.19.1
May 18, 2026
bb42ecc
fix(security): drop deprecated failNoSignature param on pgpverify 1.19.1
May 18, 2026
5c1daf4
fix(security): pin Maven lifecycle plugin versions (Category A drift)
May 18, 2026
f2dc22b
chore(diag): add POM transit diagnostic for Category B PGP failures
May 18, 2026
c897d31
fix(security): add keysmap entries for pinned lifecycle plugins (Cate…
May 18, 2026
447a4e2
chore(diag): also fire POM transit diagnostic on push to ci-fix-jfrog
May 18, 2026
fa0512b
fix(security): badSig overrides for 6 POMs byte-mutated by db-maven (…
May 18, 2026
8672256
fix(ci): bump setuptools to 80.9.0 for PEP 639 SPDX license parsing
May 18, 2026
c0a6b2f
fix(build): set project.build.sourceEncoding to silence platform-enco…
May 18, 2026
c9d836a
feat(test): per-suite progress reporter + per-test durations
May 18, 2026
fde207a
fix(python): switch project.license to PEP 639 SPDX form
May 18, 2026
fa0ed86
feat(test): show suite #N/M progress with auto-discovered total
May 18, 2026
e32c178
fix(python): drop License Trove classifier — PEP 639 forbids overlap
May 18, 2026
da10881
fix(test): filter ProgressReporter total to runnable Suite classes only
May 18, 2026
be883e3
fix(test): decrement progress M when a SuiteCompleted reports 0 tests
May 18, 2026
ee64cca
fix(test): honor -Dsuites filter in ProgressReporter discovery
May 18, 2026
dc98373
fix(test): forward Maven `suites` property into test JVM as `gbx.suites`
May 18, 2026
c265d5f
chore(docs): rebuild doc-snippet-inventory.json [skip ci]
github-actions[bot] May 18, 2026
89d546f
style(python): satisfy isort + black for PR lint gate
May 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .github/actions/jfrog-pip-bootstrap/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: 'Bootstrap pip JFrog routing (pre-setup-python)'
description: |
Acquire a JFrog OIDC access token and pre-configure pip + netrc so that any
pip invocation routes through the JFrog db-pypi mirror instead of pypi.org —
including actions/setup-python's internal "Upgrading pip" step, which runs
before any other action gets a chance to redirect pip.

Why this exists: the Databricks hardened runner groups (larger-runners,
databrickslabs-protected-runner-group) block egress to pypi.org by design;
the go/hardened-gha policy is that all package fetches go through JFrog.
Without this pre-bootstrap, setup-python's bundled "pip install --upgrade pip"
hits pypi.org and dies with SSL EOF before .github/actions/jfrog-auth
ever gets to configure pip.

Reuses the OIDC exchange script from .github/actions/jfrog-auth/jfrog-auth
to avoid duplicating curl logic that we keep in sync with UCX. The main
jfrog-auth composite still runs later in the same job (idempotent for pip;
primary for Maven, which needs setup-java to have run first).

Caller job MUST declare:
permissions:
id-token: write
runs:
using: "composite"
steps:
- id: jfrog-auth
name: Acquire JFrog OIDC access token
shell: bash
run: |
if [[ -z "${ACTIONS_ID_TOKEN_REQUEST_URL}" ]] || [[ -z "${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" ]]; then
printf '::error::%s\n' 'This action uses OIDC: job must have "id-token: write" permission'
exit 1
fi
"${GITHUB_WORKSPACE}/.github/actions/jfrog-auth/jfrog-auth" \
"${ACTIONS_ID_TOKEN_REQUEST_URL}" \
"${ACTIONS_ID_TOKEN_REQUEST_TOKEN}"

- name: Write pip.conf + netrc for JFrog (db-pypi)
shell: bash
env:
JFROG_ACCESS_TOKEN: "${{ steps.jfrog-auth.outputs.jfrog-access-token }}"
run: |
umask 077
cat > "${RUNNER_TEMP}/.netrc" << EOF
machine databricks.jfrog.io
login gha-service-account
password ${JFROG_ACCESS_TOKEN}
EOF
# Same db-pypi URL the main jfrog-auth composite uses; the later
# jfrog-auth run will overwrite this file with an identical value
# (modulo a fresh token in netrc) — idempotent by design.
cat > "${RUNNER_TEMP}/.pip.conf" << 'EOF'
[global]
index-url = https://databricks.jfrog.io/artifactory/api/pypi/db-pypi/simple
EOF
printf '%s=%s\n' 'NETRC' "${RUNNER_TEMP}/.netrc" >> "${GITHUB_ENV}"
printf '%s=%s\n' 'PIP_CONFIG_FILE' "${RUNNER_TEMP}/.pip.conf" >> "${GITHUB_ENV}"
printf '::debug::%s\n' 'Pre-bootstrap: configured JFrog access for pip.'
13 changes: 11 additions & 2 deletions .github/actions/python_build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,24 @@ inputs:
runs:
using: "composite"
steps:
# Pre-route pip at db-pypi BEFORE actions/setup-python runs: setup-python's
# python-versions installer unconditionally runs `pip install --upgrade pip`,
# which on the hardened runner group hits the egress allowlist and fails
# SSL-EOF against pypi.org. This step writes netrc + pip.conf so that
# internal pip call (and every later one) routes through JFrog instead.
# Idempotent if scala_build already ran in the same job — the env vars
# NETRC + PIP_CONFIG_FILE just get re-set to the same paths with a fresh token.
- name: Pre-bootstrap pip for JFrog (pre-setup-python)
uses: ./.github/actions/jfrog-pip-bootstrap
- name: Configure python interpreter
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
cache: 'pip'
cache-dependency-path: '.ci-pip-cache-key'
python-version: ${{ matrix.python }}
# Route pip through JFrog (OIDC) per go/hardened-gha policy.
# Idempotent if scala_build already ran in the same job (re-auths but env vars stay set).
# Caller job must declare `permissions: id-token: write`.
# Idempotent: jfrog-pip-bootstrap already configured pip; this re-runs the
# same write with a fresh token. Caller job must declare `permissions: id-token: write`.
- name: Authenticate for JFrog (pip via OIDC)
uses: ./.github/actions/jfrog-auth
- name: Add packaged GDAL dependencies
Expand Down
15 changes: 12 additions & 3 deletions .github/actions/scala_build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,25 @@ runs:
- name: Set Maven opts for coverage and parallel builds
shell: bash
run: echo "MAVEN_OPTS=-Xmx4g -XX:+UseG1GC" >> $GITHUB_ENV
# Pre-route pip at db-pypi BEFORE actions/setup-python runs: setup-python's
# python-versions installer unconditionally runs `pip install --upgrade pip`,
# which on the hardened runner group hits the egress allowlist and fails
# SSL-EOF against pypi.org. This step writes netrc + pip.conf so that
# internal pip call (and every later one) routes through JFrog instead.
- name: Pre-bootstrap pip for JFrog (pre-setup-python)
uses: ./.github/actions/jfrog-pip-bootstrap
- name: Configure python interpreter
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
cache: 'pip' # caches dependencies for faster subsequent runs
cache-dependency-path: '.ci-pip-cache-key'
python-version: ${{ matrix.python }}
# Route pip + Maven through JFrog (OIDC) per go/hardened-gha policy.
# Must run after setup-java + setup-python so mvn + pip3 are on PATH for auto-detect.
# Route Maven through JFrog (OIDC) per go/hardened-gha policy. Pip was
# already configured by jfrog-pip-bootstrap above; this re-runs pip's
# netrc/pip.conf write idempotently with a fresh token, and configures
# Maven now that setup-java has put mvn + ~/.m2/settings.xml in place.
# Caller job must declare `permissions: id-token: write`.
- name: Authenticate for JFrog (pip + Maven via OIDC)
- name: Authenticate for JFrog (Maven + pip refresh via OIDC)
uses: ./.github/actions/jfrog-auth
# Verify the PGP signature of every Maven dependency / plugin against
# .maven-keys.list BEFORE any other mvn call resolves or compiles them.
Expand Down
59 changes: 59 additions & 0 deletions .github/workflows/diag-pgpverify-pom-transit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Diag — POM transit (db-maven vs Maven Central)
# One-shot diagnostic for Category B PGP failures: "PGP Signature INVALID"
# on .pom files only (never .jar). Hypothesis: db-maven JFrog mirror is
# mutating POM bytes between Maven Central and the CI runner, breaking the
# upstream signature.
#
# This workflow fetches each suspect .pom + .pom.asc from db-maven (the
# exact path Maven uses in CI), computes sha256, and compares against a
# known reference from Maven Central (recorded inside the script). Mismatch
# = byte mutation confirmed; match = signature failure has a different
# root cause.
#
# Manual trigger only (workflow_dispatch). Delete this workflow once the
# investigation concludes. Run blocks contain no untrusted github.event.*
# values — only static script invocations.

on:
# workflow_dispatch is the long-term trigger, but it only works once the
# workflow file lands on the default branch. While this diagnostic lives
# only on ci-fix-jfrog, also fire on push that touches the diag script
# or the workflow itself so we can actually run it. Remove the push
# trigger once the diagnostic concludes and the workflow is deleted.
workflow_dispatch: {}
push:
branches:
- 'ci-fix-jfrog'
paths:
- 'scripts/security/diag-pgpverify-pom-transit'
- '.github/workflows/diag-pgpverify-pom-transit.yml'

permissions:
contents: read

jobs:
diag:
name: pom-transit-diff
runs-on:
group: databrickslabs-protected-runner-group
labels: linux-ubuntu-latest
environment: runtime
permissions:
contents: read
id-token: write
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
token: ${{ secrets.REPO_ACCESS_TOKEN || secrets.GITHUB_TOKEN }}
- name: Configure JDK
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
java-version: '17'
distribution: 'zulu'
- name: Authenticate for JFrog (Maven via OIDC)
uses: ./.github/actions/jfrog-auth
- name: Install gpg (for standalone signature verification)
run: sudo apt-get -o DPkg::Lock::Timeout=-1 install -y gpg
- name: Run POM transit diagnostic
run: ./scripts/security/diag-pgpverify-pom-transit
93 changes: 89 additions & 4 deletions .maven-keys.list
Original file line number Diff line number Diff line change
Expand Up @@ -390,11 +390,8 @@ org.tukaani:xz = 0x369
antlr:antlr:jar:2.7.2 = noSig
antlr:antlr:pom:2.7.2 = noSig
com.fasterxml.jackson.core:jackson-annotations:jar:2.18.3 = noSig
com.fasterxml.jackson.core:jackson-annotations:pom:2.18.3 = noSig
com.fasterxml.jackson.core:jackson-core:jar:2.18.3 = noSig
com.fasterxml.jackson.core:jackson-core:pom:2.18.3 = noSig
com.fasterxml.jackson.core:jackson-databind:jar:2.18.3 = noSig
com.fasterxml.jackson.core:jackson-databind:pom:2.18.3 = noSig
com.github.luben:zstd-jni:jar:1.5.7-6 = noSig
com.github.luben:zstd-jni:pom:1.5.7-6 = noSig
com.google.code.findbugs:jsr305:jar:2.0.1 = noSig
Expand Down Expand Up @@ -498,7 +495,6 @@ junit:junit:pom:4.13.2
log4j:log4j:jar:1.2.12 = noSig
log4j:log4j:pom:1.2.12 = noSig
net.alchim31.maven:scala-maven-plugin:jar:4.9.9 = noSig
net.alchim31.maven:scala-maven-plugin:pom:4.9.9 = noSig
net.openhft:zero-allocation-hashing:jar:0.16 = noSig
net.openhft:zero-allocation-hashing:pom:0.16 = noSig
org.apache-extras.beanshell:bsh:jar:2.0b6 = noSig
Expand Down Expand Up @@ -1053,3 +1049,92 @@ xml-apis:xml-apis:jar:1.0.b2
xml-apis:xml-apis:jar:1.3.04 = noSig
xml-apis:xml-apis:pom:1.0.b2 = noSig
xml-apis:xml-apis:pom:1.3.04 = noSig

# --- Version-specific keyed entries surfaced by post-pin closure ----------
#
# These are lifecycle-plugin versions that pom.xml now pins explicitly
# (maven-compiler-plugin, maven-install-plugin, maven-deploy-plugin) plus
# their transitive plugin-dependencies (plexus-compiler-*, file-management).
# Newer versions are signed by Apache committers whose keys aren't on the
# Apache Maven KEYS file but ARE on keyserver.ubuntu.com with self-signed
# UIDs at apache.org addresses.
#
# Trust verification (2026-05-18):
#
# 0x84789D24DF77A32433CE1F079EB80E92EB2135B1
# uid: Slawomir Jaranowski <sjaranowski@apache.org>
# Apache Maven committer; lead developer of pgpverify-maven-plugin
# itself. Key created 2021-12-22, RSA 4096, active.
# https://keyserver.ubuntu.com/pks/lookup?op=vindex&fingerprint=on&search=0x84789D24DF77A32433CE1F079EB80E92EB2135B1
#
# 0x32118CF76C9EC5D918E54967CA80D1F0EB6CA4BA
# uid: Sylwester Lachiewicz <slachiewicz@apache.org>
# Apache committer; Mojo Codehaus / Maven plugins maintainer.
# Key created 2020-05-09, RSA 4096, active.
# https://keyserver.ubuntu.com/pks/lookup?op=vindex&fingerprint=on&search=0x32118CF76C9EC5D918E54967CA80D1F0EB6CA4BA
#
# Versions are pinned in pom.xml; bump them in lockstep with new entries here.

org.apache.maven.plugins:maven-install-plugin:jar:3.1.4 = 0x84789D24DF77A32433CE1F079EB80E92EB2135B1
org.apache.maven.plugins:maven-install-plugin:pom:3.1.4 = 0x84789D24DF77A32433CE1F079EB80E92EB2135B1
org.apache.maven.plugins:maven-deploy-plugin:jar:3.1.4 = 0x84789D24DF77A32433CE1F079EB80E92EB2135B1
org.apache.maven.plugins:maven-deploy-plugin:pom:3.1.4 = 0x84789D24DF77A32433CE1F079EB80E92EB2135B1
org.apache.maven.shared:file-management:jar:3.2.0 = 0x84789D24DF77A32433CE1F079EB80E92EB2135B1
org.apache.maven.shared:file-management:pom:3.2.0 = 0x84789D24DF77A32433CE1F079EB80E92EB2135B1
org.apache.maven.plugins:maven-compiler-plugin:jar:3.15.0 = 0x32118CF76C9EC5D918E54967CA80D1F0EB6CA4BA
org.apache.maven.plugins:maven-compiler-plugin:pom:3.15.0 = 0x32118CF76C9EC5D918E54967CA80D1F0EB6CA4BA
org.codehaus.plexus:plexus-compiler-api:jar:2.16.2 = 0x32118CF76C9EC5D918E54967CA80D1F0EB6CA4BA
org.codehaus.plexus:plexus-compiler-api:pom:2.16.2 = 0x32118CF76C9EC5D918E54967CA80D1F0EB6CA4BA
org.codehaus.plexus:plexus-compiler-javac:jar:2.16.2 = 0x32118CF76C9EC5D918E54967CA80D1F0EB6CA4BA
org.codehaus.plexus:plexus-compiler-javac:pom:2.16.2 = 0x32118CF76C9EC5D918E54967CA80D1F0EB6CA4BA
org.codehaus.plexus:plexus-compiler-manager:jar:2.16.2 = 0x32118CF76C9EC5D918E54967CA80D1F0EB6CA4BA
org.codehaus.plexus:plexus-compiler-manager:pom:2.16.2 = 0x32118CF76C9EC5D918E54967CA80D1F0EB6CA4BA

# --- badSig overrides for POMs byte-mutated by db-maven JFrog mirror -----
#
# These six .pom files fail pgpverify-maven-plugin with "PGP Signature
# INVALID" — cryptographic verification of the .asc against the bytes
# fails. The corresponding .jar files for the same artifacts verify
# OK (they're binary and pass through JFrog untouched).
#
# Root cause confirmed 2026-05-18 via the diag-pgpverify-pom-transit
# workflow (run 26056343517 on branch ci-fix-jfrog):
#
# * .pom sha256 from db-maven DIFFERS from Maven Central (size delta
# -348 to +170 bytes per file)
# * .pom.asc sha256 from db-maven MATCHES Maven Central (signatures
# untouched)
# * Hex dump shows LF → CRLF conversion at every line end, plus
# additional content normalization (whitespace / XML formatting)
# * Standalone `gpg --verify` on the db-maven bytes produces "Signature
# made … using RSA key … Can't check signature" — the .asc was
# computed against the original Maven Central bytes, not the
# JFrog-mutated ones.
#
# JFrog db-maven applies some form of text-resource transformation to
# .pom files on the mirror side, which breaks the upstream PGP signature
# chain. The .jar signatures remain trustworthy (binary, untouched), so
# code-execution integrity is still gated. POM-declared dependency
# coordinates inherit JFrog-as-trust-boundary status (an attacker who
# compromises db-maven could regress to a previously-trusted-but-now-
# vulnerable signed JAR via POM rewrite — risk is real but bounded
# to artifacts already in the mirror's allowlist).
#
# `badSig` here means "tolerate that the .pom signature does not
# cryptographically verify" — narrower than `noSig` ("tolerate no
# signature at all"). The artifact must still HAVE a .asc on the
# server; this only suppresses the crypto-failure error.
#
# Action item: file a JFrog admin ticket asking db-maven to disable
# text-artifact transformations so POM bytes pass through verbatim, then
# delete this block (POMs will verify again).
#
# Versions are pinned at the exact artifact:packaging:version level so
# future releases inherit strict verification rather than the override.

com.fasterxml.jackson.core:jackson-annotations:pom:2.18.3 = badSig
com.fasterxml.jackson.core:jackson-core:pom:2.18.3 = badSig
com.fasterxml.jackson.core:jackson-databind:pom:2.18.3 = badSig
javax.servlet:javax.servlet-api:pom:3.1.0 = badSig
net.alchim31.maven:scala-maven-plugin:pom:4.9.9 = badSig
org.iq80.snappy:snappy:pom:0.4 = badSig
Loading
Loading