npm(deps): bump the npm-minor-and-patch group across 1 directory with… #69
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
| # Workflow for building Next.js site and downloading DocumentDB packages, then deploying to GitHub Pages | |
| name: Deploy Next.js site and DocumentDB packages to Pages | |
| on: | |
| # Runs on pushes targeting the default branch | |
| push: | |
| branches: | |
| - main | |
| # Allows you to run this workflow manually from the Actions tab | |
| workflow_dispatch: | |
| # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. | |
| # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. | |
| concurrency: | |
| group: pages | |
| cancel-in-progress: false | |
| jobs: | |
| # Build job | |
| build: | |
| name: Build Next.js static site | |
| # Sets permissions of the GITHUB_TOKEN to allow reading of repository content | |
| permissions: | |
| contents: read | |
| runs-on: ubuntu-22.04 | |
| # Without an explicit timeout a stalled step runs against GitHub's 6-hour | |
| # default before failing, which for `pages` concurrency means blocking | |
| # every deployment queued behind it. | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Checkout source | |
| uses: actions/checkout@v7 | |
| - name: Resolve optional build features | |
| # The static site is always built. Mirroring the release packages and | |
| # signing them are separate opt-outs so that a fork with no secrets can | |
| # still run this workflow end to end. | |
| id: features | |
| env: | |
| # The `secrets` context is not readable from a step-level `if:`, so | |
| # the presence of the signing key has to be resolved into a step | |
| # output first. Binding the secret to this one step also keeps it out | |
| # of every other step's environment. | |
| GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} | |
| # A fork has neither the signing key nor a reason to spend several | |
| # minutes mirroring release assets, so package generation defaults | |
| # off outside this repository. `BUILD_PACKAGES` overrides it either | |
| # way - but note that turning it off upstream publishes a site with | |
| # no /deb, /rpm and no keyring, which breaks `apt-get update` for | |
| # everyone already pointed at the repository. | |
| BUILD_PACKAGES: ${{ vars.BUILD_PACKAGES }} | |
| IS_UPSTREAM: ${{ github.repository == 'documentdb/documentdb.github.io' }} | |
| run: | | |
| set -euo pipefail | |
| requested=$(printf '%s' "$BUILD_PACKAGES" | tr '[:upper:]' '[:lower:]') | |
| case "$requested" in | |
| true|false) packages="$requested" ;; | |
| '') packages="$IS_UPSTREAM" ;; | |
| *) | |
| echo "::error::BUILD_PACKAGES must be 'true' or 'false' (got '$BUILD_PACKAGES')" | |
| exit 1 | |
| ;; | |
| esac | |
| if [ "$packages" = 'true' ] && [ -n "$GPG_PRIVATE_KEY" ]; then | |
| sign=true | |
| else | |
| sign=false | |
| fi | |
| echo "packages=$packages" >> "$GITHUB_OUTPUT" | |
| echo "sign=$sign" >> "$GITHUB_OUTPUT" | |
| { | |
| echo "### Build configuration" | |
| echo "" | |
| echo "| Feature | Enabled | Controlled by |" | |
| echo "| --- | --- | --- |" | |
| echo "| Static site | true | always built |" | |
| echo "| Package repositories | $packages | \`BUILD_PACKAGES\` variable |" | |
| echo "| Package signing | $sign | \`GPG_PRIVATE_KEY\` secret |" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| if [ "$packages" = 'true' ] && [ "$sign" != 'true' ]; then | |
| echo "::warning::GPG_PRIVATE_KEY is not set - the package repositories will be published unsigned." | |
| fi | |
| - name: Install packaging tools | |
| if: steps.features.outputs.packages == 'true' | |
| run: | | |
| until sudo apt-get update; do sleep 1; done | |
| sudo apt-get install -y createrepo-c dpkg-dev dpkg-sig gnupg2 python3 | |
| - name: Setup GPG | |
| id: import_gpg | |
| if: steps.features.outputs.sign == 'true' | |
| # Deliberately no `continue-on-error`: a key that is configured but | |
| # cannot be imported has to fail the run. Swallowing that error | |
| # republishes the site with an unsigned repository in place of a signed | |
| # one, which breaks `apt-get update` for every client pinned with | |
| # `signed-by`. Signing is optional; silently losing it is not. | |
| uses: crazy-max/ghaction-import-gpg@v7 | |
| with: | |
| gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} | |
| - name: Configure package build | |
| if: steps.features.outputs.packages == 'true' | |
| env: | |
| SIGN: ${{ steps.features.outputs.sign }} | |
| FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} | |
| KEY_ID: ${{ steps.import_gpg.outputs.keyid }} | |
| KEY_NAME: ${{ steps.import_gpg.outputs.name }} | |
| KEY_EMAIL: ${{ steps.import_gpg.outputs.email }} | |
| # Configure which DocumentDB release to mirror. Both can be | |
| # overridden by repository variables. | |
| DOCUMENTDB_VERSION: ${{ vars.DOCUMENTDB_VERSION || 'latest' }} | |
| MULTI_VERSION: ${{ vars.MULTI_VERSION || 'true' }} | |
| run: | | |
| set -euo pipefail | |
| if [ "$SIGN" = 'true' ]; then | |
| if [ -z "$FINGERPRINT" ]; then | |
| echo "::error::The GPG key imported without a fingerprint; refusing to publish an unsigned repository." | |
| exit 1 | |
| fi | |
| echo "GPG_FINGERPRINT=$FINGERPRINT" >> "$GITHUB_ENV" | |
| echo "GPG key loaded successfully" | |
| echo " Fingerprint: $FINGERPRINT" | |
| echo " Key ID: $KEY_ID" | |
| echo " User ID: $KEY_NAME <$KEY_EMAIL>" | |
| else | |
| echo "No GPG key configured - packages will not be signed." | |
| echo "To enable signing, add GPG_PRIVATE_KEY to the repository secrets." | |
| fi | |
| echo "DOCUMENTDB_VERSION=$DOCUMENTDB_VERSION" >> "$GITHUB_ENV" | |
| echo "MULTI_VERSION=$MULTI_VERSION" >> "$GITHUB_ENV" | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v7 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| - name: Setup Ruby | |
| uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: 3.3 | |
| bundler-cache: true | |
| - name: Restore cache | |
| uses: actions/cache@v6 | |
| with: | |
| path: | | |
| .next/cache | |
| # Generate a new cache whenever packages or source files change. | |
| key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }} | |
| # If source files changed but packages didn't, rebuild from a prior cache. | |
| restore-keys: | | |
| ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}- | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build with Next.js | |
| # This repository is the organization Pages site served at the root of | |
| # the custom domain (documentdb.io), so the build must NOT set | |
| # NEXT_BASE_PATH. Setting it to the repository name (the usual trick | |
| # for project pages) prefixes every internal link and asset URL with | |
| # /documentdb.github.io/, which GitHub Pages then 301-redirects back | |
| # to the root on every request and leaves the prefixed URL visible in | |
| # the address bar after client-side navigation. | |
| env: | |
| JEKYLL_BASE_PATH: /blogs | |
| run: npm run build | |
| - name: Verify exported documentation pages | |
| # A partially failed content compile must never reach production as a | |
| # docs-less site. compile-content fails the build on clone/copy errors; | |
| # this is the independent belt-and-braces check on the final artifact. | |
| run: | | |
| set -euo pipefail | |
| for page in out/index.html out/docs/index.html out/docs/getting-started/index.html out/docs/reference/index.html; do | |
| if [ ! -f "$page" ]; then | |
| echo "Missing expected page: $page" | |
| exit 1 | |
| fi | |
| done | |
| reference_count=$(find out/docs/reference -name index.html | wc -l) | |
| echo "Reference pages exported: $reference_count" | |
| # The docs repo currently holds ~240 reference entries; well under | |
| # half of that means the compile silently lost content. | |
| if [ "$reference_count" -lt 100 ]; then | |
| echo "Only $reference_count reference pages exported - documentation content looks incomplete." | |
| exit 1 | |
| fi | |
| - name: Download DocumentDB packages from latest release | |
| if: steps.features.outputs.packages == 'true' | |
| run: .github/scripts/download_packages.sh | |
| - name: Verify generated package components | |
| if: steps.features.outputs.packages == 'true' | |
| env: | |
| SIGN: ${{ steps.features.outputs.sign }} | |
| run: | | |
| set -euo pipefail | |
| python3 - <<'PY' | |
| import json | |
| import os | |
| from pathlib import Path | |
| release_info = Path("out/packages/release-info.json") | |
| if not release_info.exists(): | |
| raise SystemExit("release-info.json was not generated") | |
| data = json.loads(release_info.read_text()) | |
| assets = [asset["name"] for asset in data.get("assets", [])] | |
| components = ("deb11", "deb12", "deb13", "ubuntu22", "ubuntu24") | |
| for component in components: | |
| has_assets = any( | |
| name.endswith(".deb") | |
| and ( | |
| name.startswith(f"{component}-") | |
| or name.startswith(f"{component}.04-") | |
| ) | |
| for name in assets | |
| ) | |
| if not has_assets: | |
| continue | |
| for arch in ("amd64", "arm64"): | |
| packages = Path(f"out/deb/dists/stable/{component}/binary-{arch}/Packages") | |
| packages_gz = Path(f"out/deb/dists/stable/{component}/binary-{arch}/Packages.gz") | |
| if not packages.exists() or not packages_gz.exists(): | |
| raise SystemExit( | |
| f"Missing APT metadata for {component} {arch}: " | |
| f"{packages} / {packages_gz}" | |
| ) | |
| release_file = Path("out/deb/dists/stable/Release") | |
| if release_file.exists() and any(name.startswith("deb13-") and name.endswith(".deb") for name in assets): | |
| release_text = release_file.read_text() | |
| if "deb13" not in release_text: | |
| raise SystemExit("deb13 assets exist but deb13 is missing from the APT Release file") | |
| # A run that imported a signing key must not publish an unsigned | |
| # repository: apt rejects a suite whose InRelease/Release.gpg vanished, | |
| # so a silently skipped signature is a client-visible outage rather | |
| # than a cosmetic regression. | |
| if os.environ.get("SIGN") == "true": | |
| if any(name.endswith(".deb") for name in assets): | |
| for artifact in ( | |
| Path("out/deb/dists/stable/Release.gpg"), | |
| Path("out/deb/dists/stable/InRelease"), | |
| Path("out/documentdb-archive-keyring.gpg"), | |
| ): | |
| if not artifact.exists(): | |
| raise SystemExit( | |
| f"Signing was enabled but {artifact} was not produced" | |
| ) | |
| # RPM metadata signing is best-effort inside the download script, | |
| # so surface it as a warning instead of failing the deployment. | |
| for repomd in sorted(Path("out/rpm").glob("*/repodata/repomd.xml")): | |
| if not Path(f"{repomd}.asc").exists(): | |
| print(f"::warning::{repomd} was not signed") | |
| PY | |
| - name: Upload artifact | |
| uses: actions/upload-pages-artifact@v5 | |
| with: | |
| path: ./out | |
| # Deployment job | |
| deploy: | |
| name: Publish site to GitHub Pages | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| needs: | |
| - build | |
| # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages | |
| permissions: | |
| pages: write | |
| id-token: write | |
| steps: | |
| - name: Setup Pages | |
| uses: actions/configure-pages@v6 | |
| with: | |
| # Automatically inject basePath in your Next.js configuration file and disable | |
| # server side image optimization (https://nextjs.org/docs/api-reference/next/image#unoptimized). | |
| # | |
| # You may remove this line if you want to manage the configuration yourself. | |
| static_site_generator: next | |
| - name: Deploy to GitHub Pages | |
| id: deployment | |
| uses: actions/deploy-pages@v5 |