2.0.0: breaking security bump — Node >=20, thrift 0.23, uuid 11, lz4→lz4-napi (0 OSV findings) #1118
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: test | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| branches: | |
| - main | |
| permissions: | |
| contents: read | |
| id-token: write | |
| jobs: | |
| lint: | |
| runs-on: | |
| group: databricks-protected-runner-group | |
| labels: linux-ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: 20 | |
| - uses: ./.github/actions/setup-jfrog | |
| - name: Cache node modules | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 | |
| env: | |
| cache-name: cache-node-modules | |
| with: | |
| path: ~/.npm | |
| key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-build-${{ env.cache-name }}- | |
| ${{ runner.os }}-build- | |
| ${{ runner.os }}- | |
| # DIAGNOSTIC (temporary — remove once npm-hang root cause identified). | |
| # Captures effective npm config, lockfile registry distribution, and | |
| # registry reachability BEFORE npm ci runs. | |
| - name: Diag — pre-npm-ci | |
| run: | | |
| set +e | |
| echo "=== effective npm config ===" | |
| npm config list -l 2>&1 | grep -E '^(registry|fetch-|cache|loglevel|prefer-|@databricks)' || true | |
| echo "=== ~/.npmrc (auth masked) ===" | |
| sed 's/_authToken=.*/_authToken=***/' ~/.npmrc 2>/dev/null || echo "(no ~/.npmrc)" | |
| echo "=== npm cache dir ===" | |
| npm config get cache | |
| ls -la "$(npm config get cache)" 2>/dev/null | head -10 || echo "(empty)" | |
| echo "=== package-lock.json resolved URLs by registry ===" | |
| grep -oE '"resolved": "https://[^/]+' package-lock.json | sort | uniq -c | |
| echo "=== reachability probes ===" | |
| for url in https://registry.npmjs.org/ https://databricks.jfrog.io/artifactory/api/npm/db-npm/; do | |
| echo "--- $url ---" | |
| curl -sS -o /dev/null -w "HTTP=%{http_code} connect=%{time_connect}s total=%{time_total}s\n" \ | |
| --max-time 10 --connect-timeout 5 \ | |
| -H "Authorization: Bearer $JFROG_ACCESS_TOKEN" \ | |
| "$url" || echo "FAIL (curl exit $?)" | |
| done | |
| echo "=== sample package metadata fetch (basic-ftp, new in this PR) ===" | |
| curl -sS -o /tmp/probe.json -w "basic-ftp: HTTP=%{http_code} size=%{size_download}b time=%{time_total}s\n" \ | |
| --max-time 10 -H "Authorization: Bearer $JFROG_ACCESS_TOKEN" \ | |
| "https://databricks.jfrog.io/artifactory/api/npm/db-npm/basic-ftp" || echo "FAIL" | |
| head -c 200 /tmp/probe.json 2>/dev/null; echo | |
| echo "=== /probe ===" | |
| true | |
| - name: Check code style | |
| run: | | |
| npm ci --loglevel=http --no-progress --foreground-scripts | |
| npm run prettier | |
| npm run lint | |
| # DIAGNOSTIC (temporary — remove once npm-hang root cause identified). | |
| # Captures npm debug log, cache state, and node_modules state AFTER | |
| # the failure so we can see exactly what npm did during the silent | |
| # 8-minute hang. | |
| - name: Diag — post-npm-ci on failure | |
| if: failure() | |
| run: | | |
| set +e | |
| DIAG=/tmp/npm-diag | |
| mkdir -p "$DIAG" | |
| cp -r ~/.npm/_logs "$DIAG/npm_logs" 2>/dev/null || echo "no _logs dir" | |
| du -sh ~/.npm/_cacache 2>/dev/null > "$DIAG/cacache_size.txt" | |
| ls -la node_modules/.bin/ 2>/dev/null > "$DIAG/node_modules_bin.txt" || echo "(no .bin)" > "$DIAG/node_modules_bin.txt" | |
| ls node_modules/ 2>/dev/null | wc -l > "$DIAG/node_modules_pkg_count.txt" | |
| ps auxf > "$DIAG/ps_snapshot.txt" 2>&1 || true | |
| dmesg 2>&1 | tail -50 > "$DIAG/dmesg_tail.txt" || true | |
| cp package-lock.json "$DIAG/package-lock.json.in-ci" | |
| echo "=== diag bundle contents ===" | |
| ls -la "$DIAG" | |
| true | |
| - name: Diag — upload bundle | |
| if: failure() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: npm-diag-lint | |
| path: /tmp/npm-diag | |
| if-no-files-found: warn | |
| retention-days: 7 | |
| unit-test: | |
| runs-on: | |
| group: databricks-protected-runner-group | |
| labels: linux-ubuntu-latest | |
| strategy: | |
| matrix: | |
| # only LTS versions starting from the lowest we support. | |
| # Node 14 was dropped: the modern npm ecosystem (e.g. | |
| # @dabh/diagnostics@2.0.7+ via winston) now ships ES2021 | |
| # syntax (||=) that Node 14's V8 cannot parse. Node 14 | |
| # has been EOL upstream since April 2023. | |
| node-version: ['16', '18', '20'] | |
| env: | |
| cache-name: cache-node-modules | |
| NYC_REPORT_DIR: coverage_unit_node${{ matrix.node-version }} | |
| steps: | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - uses: ./.github/actions/setup-jfrog | |
| - name: Cache node modules | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 | |
| with: | |
| path: ~/.npm | |
| key: ${{ runner.os }}-${{ matrix.node-version }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-${{ matrix.node-version }}-build-${{ env.cache-name }}- | |
| ${{ runner.os }}-${{ matrix.node-version }}-build- | |
| ${{ runner.os }}-${{ matrix.node-version }}- | |
| - name: Diag — pre-npm-ci | |
| run: | | |
| set +e | |
| echo "=== effective npm config ===" | |
| npm config list -l 2>&1 | grep -E '^(registry|fetch-|cache|loglevel|prefer-|@databricks)' || true | |
| echo "=== ~/.npmrc (auth masked) ===" | |
| sed 's/_authToken=.*/_authToken=***/' ~/.npmrc 2>/dev/null || echo "(no ~/.npmrc)" | |
| echo "=== npm cache dir ===" | |
| npm config get cache | |
| ls -la "$(npm config get cache)" 2>/dev/null | head -10 || echo "(empty)" | |
| echo "=== package-lock.json resolved URLs by registry ===" | |
| grep -oE '"resolved": "https://[^/]+' package-lock.json | sort | uniq -c | |
| echo "=== reachability probes ===" | |
| for url in https://registry.npmjs.org/ https://databricks.jfrog.io/artifactory/api/npm/db-npm/; do | |
| echo "--- $url ---" | |
| curl -sS -o /dev/null -w "HTTP=%{http_code} connect=%{time_connect}s total=%{time_total}s\n" \ | |
| --max-time 10 --connect-timeout 5 \ | |
| -H "Authorization: Bearer $JFROG_ACCESS_TOKEN" \ | |
| "$url" || echo "FAIL (curl exit $?)" | |
| done | |
| echo "=== sample package metadata fetch (basic-ftp, new in this PR) ===" | |
| curl -sS -o /tmp/probe.json -w "basic-ftp: HTTP=%{http_code} size=%{size_download}b time=%{time_total}s\n" \ | |
| --max-time 10 -H "Authorization: Bearer $JFROG_ACCESS_TOKEN" \ | |
| "https://databricks.jfrog.io/artifactory/api/npm/db-npm/basic-ftp" || echo "FAIL" | |
| head -c 200 /tmp/probe.json 2>/dev/null; echo | |
| echo "=== /probe ===" | |
| true | |
| - name: Run unit tests | |
| run: | | |
| npm ci --loglevel=http --no-progress --foreground-scripts | |
| npm run test | |
| - name: Diag — post-npm-ci on failure | |
| if: failure() | |
| run: | | |
| set +e | |
| DIAG=/tmp/npm-diag | |
| mkdir -p "$DIAG" | |
| cp -r ~/.npm/_logs "$DIAG/npm_logs" 2>/dev/null || echo "no _logs dir" | |
| du -sh ~/.npm/_cacache 2>/dev/null > "$DIAG/cacache_size.txt" | |
| ls -la node_modules/.bin/ 2>/dev/null > "$DIAG/node_modules_bin.txt" || echo "(no .bin)" > "$DIAG/node_modules_bin.txt" | |
| ls node_modules/ 2>/dev/null | wc -l > "$DIAG/node_modules_pkg_count.txt" | |
| ps auxf > "$DIAG/ps_snapshot.txt" 2>&1 || true | |
| dmesg 2>&1 | tail -50 > "$DIAG/dmesg_tail.txt" || true | |
| cp package-lock.json "$DIAG/package-lock.json.in-ci" | |
| echo "=== diag bundle contents ===" | |
| ls -la "$DIAG" | |
| true | |
| - name: Diag — upload bundle | |
| if: failure() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: npm-diag-unit-test-node${{ matrix.node-version }} | |
| path: /tmp/npm-diag | |
| if-no-files-found: warn | |
| retention-days: 7 | |
| - run: tar -cvf ${{ env.NYC_REPORT_DIR }}.tar ${{ env.NYC_REPORT_DIR }} | |
| - name: Store coverage report | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: ${{ env.NYC_REPORT_DIR }} | |
| path: ${{ env.NYC_REPORT_DIR }}.tar | |
| retention-days: 1 | |
| e2e-test: | |
| runs-on: | |
| group: databricks-protected-runner-group | |
| labels: linux-ubuntu-latest | |
| environment: azure-prod | |
| env: | |
| E2E_HOST: ${{ secrets.DATABRICKS_HOST }} | |
| E2E_PATH: ${{ secrets.TEST_PECO_WAREHOUSE_HTTP_PATH }} | |
| E2E_ACCESS_TOKEN: ${{ secrets.DATABRICKS_TOKEN }} | |
| E2E_TABLE_SUFFIX: ${{github.sha}} | |
| E2E_CATALOG: peco | |
| E2E_SCHEMA: default | |
| E2E_VOLUME: e2etests | |
| cache-name: cache-node-modules | |
| NYC_REPORT_DIR: coverage_e2e | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: 20 | |
| - uses: ./.github/actions/setup-jfrog | |
| - name: Cache node modules | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 | |
| with: | |
| path: ~/.npm | |
| key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-build-${{ env.cache-name }}- | |
| ${{ runner.os }}-build- | |
| ${{ runner.os }}- | |
| - name: Diag — pre-npm-ci | |
| run: | | |
| set +e | |
| echo "=== effective npm config ===" | |
| npm config list -l 2>&1 | grep -E '^(registry|fetch-|cache|loglevel|prefer-|@databricks)' || true | |
| echo "=== ~/.npmrc (auth masked) ===" | |
| sed 's/_authToken=.*/_authToken=***/' ~/.npmrc 2>/dev/null || echo "(no ~/.npmrc)" | |
| echo "=== npm cache dir ===" | |
| npm config get cache | |
| ls -la "$(npm config get cache)" 2>/dev/null | head -10 || echo "(empty)" | |
| echo "=== package-lock.json resolved URLs by registry ===" | |
| grep -oE '"resolved": "https://[^/]+' package-lock.json | sort | uniq -c | |
| echo "=== reachability probes ===" | |
| for url in https://registry.npmjs.org/ https://databricks.jfrog.io/artifactory/api/npm/db-npm/; do | |
| echo "--- $url ---" | |
| curl -sS -o /dev/null -w "HTTP=%{http_code} connect=%{time_connect}s total=%{time_total}s\n" \ | |
| --max-time 10 --connect-timeout 5 \ | |
| -H "Authorization: Bearer $JFROG_ACCESS_TOKEN" \ | |
| "$url" || echo "FAIL (curl exit $?)" | |
| done | |
| echo "=== sample package metadata fetch (basic-ftp, new in this PR) ===" | |
| curl -sS -o /tmp/probe.json -w "basic-ftp: HTTP=%{http_code} size=%{size_download}b time=%{time_total}s\n" \ | |
| --max-time 10 -H "Authorization: Bearer $JFROG_ACCESS_TOKEN" \ | |
| "https://databricks.jfrog.io/artifactory/api/npm/db-npm/basic-ftp" || echo "FAIL" | |
| head -c 200 /tmp/probe.json 2>/dev/null; echo | |
| echo "=== /probe ===" | |
| true | |
| - name: Run e2e tests | |
| run: | | |
| npm ci --loglevel=http --no-progress --foreground-scripts | |
| NODE_OPTIONS="--max-old-space-size=4096" npm run e2e | |
| - name: Diag — post-npm-ci on failure | |
| if: failure() | |
| run: | | |
| set +e | |
| DIAG=/tmp/npm-diag | |
| mkdir -p "$DIAG" | |
| cp -r ~/.npm/_logs "$DIAG/npm_logs" 2>/dev/null || echo "no _logs dir" | |
| du -sh ~/.npm/_cacache 2>/dev/null > "$DIAG/cacache_size.txt" | |
| ls -la node_modules/.bin/ 2>/dev/null > "$DIAG/node_modules_bin.txt" || echo "(no .bin)" > "$DIAG/node_modules_bin.txt" | |
| ls node_modules/ 2>/dev/null | wc -l > "$DIAG/node_modules_pkg_count.txt" | |
| ps auxf > "$DIAG/ps_snapshot.txt" 2>&1 || true | |
| dmesg 2>&1 | tail -50 > "$DIAG/dmesg_tail.txt" || true | |
| cp package-lock.json "$DIAG/package-lock.json.in-ci" | |
| echo "=== diag bundle contents ===" | |
| ls -la "$DIAG" | |
| true | |
| - name: Diag — upload bundle | |
| if: failure() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: npm-diag-e2e-test | |
| path: /tmp/npm-diag | |
| if-no-files-found: warn | |
| retention-days: 7 | |
| - run: tar -cvf ${{ env.NYC_REPORT_DIR }}.tar ${{ env.NYC_REPORT_DIR }} | |
| - name: Store coverage report | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: ${{ env.NYC_REPORT_DIR }} | |
| path: ${{ env.NYC_REPORT_DIR }}.tar | |
| retention-days: 1 | |
| coverage: | |
| needs: [unit-test, e2e-test] | |
| runs-on: | |
| group: databricks-protected-runner-group | |
| labels: linux-ubuntu-latest | |
| env: | |
| cache-name: cache-node-modules | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - name: Cache node modules | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 | |
| with: | |
| path: ~/.npm | |
| key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-build-${{ env.cache-name }}- | |
| ${{ runner.os }}-build- | |
| ${{ runner.os }}- | |
| - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 | |
| with: | |
| pattern: coverage_* | |
| merge-multiple: true | |
| - name: Unpack coverage reports | |
| run: | | |
| ls -1 coverage_*.tar | xargs -I '{}' -- tar -xvf '{}' | |
| rm coverage_*.tar | |
| - run: ls -la | |
| - name: Coverage | |
| uses: codecov/codecov-action@ab904c41d6ece82784817410c45d8b8c02684457 # v3 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| fail_ci_if_error: true | |
| verbose: true |