Skip to content

npm(deps): bump the npm-minor-and-patch group across 1 directory with… #69

npm(deps): bump the npm-minor-and-patch group across 1 directory with…

npm(deps): bump the npm-minor-and-patch group across 1 directory with… #69

# 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