Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 0 additions & 3 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ name: Lint Code Base
on:
workflow_dispatch:
pull_request:
push:
branches:
- main
Comment on lines -13 to -15
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not keep this? I kinda like it as a backup in case something is missed in a PR review.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had in mind that we need a complete sequential flow - if something fails to stop the deployment.
If we run one thing on GitHub and another on Cloud Build this doesn't happen.
So the idea is to migrate everything required to deployment workflow.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree it's not needed. I just like it as an extra backup check so I can go into the Actions tab and see exactly when it started failing on the main branch. Similar to how we're seeing in har.fyi now.

Of course, ideally, it should never make it to main if it's going to cause an error. But sometimes things aren't caught in PRs...

So, while I agree it's not strictly necessary, and not part of the deploy process, I see no harm to keep it?

jobs:
lint:
name: Lint Code Base
Expand Down
94 changes: 0 additions & 94 deletions .github/workflows/predeploy.yml

This file was deleted.

3 changes: 0 additions & 3 deletions .github/workflows/test_website.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ on:
pull_request:
paths-ignore:
- 'sql/**'
push:
branches:
- main
Comment on lines -14 to -16
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not keep this? I kinda like it as a backup in case something is missed in a PR review.

jobs:
build:
name: Build and Test Website
Expand Down
142 changes: 142 additions & 0 deletions cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
######################################
## Cloud Build Deployment Pipeline ##
######################################
#
# Triggered on every push to main (i.e. when a PR is merged).
# Update the trigger at:
# https://console.cloud.google.com/cloud-build/triggers;region=us-central1/edit/2bd8fcc6-6319-455d-88f2-38d564fe2db8?project=httparchive
#
# $SHORT_SHA is set automatically by Cloud Build on a branch-push trigger.

substitutions:
# Update when a new Prince version is released: https://www.princexml.com/latest/
# python:3.12 is based on Debian Bookworm (12), so use the debian12 package.
_PRINCE_PACKAGE: 'prince_16.1-1_debian12_amd64.deb'

steps:
# ─────────────────────────────────────────────────────────────────────────
# Step 1: Install dependencies, generate all chapters, run full test suite.
# Uses python:3.12 (Debian Bookworm) and installs Node 24 at runtime.
# node_modules persist in /workspace and are reused by later steps;
# Python packages are re-installed per step.
# ─────────────────────────────────────────────────────────────────────────
- name: 'python:3.12'
id: 'build-and-test'
entrypoint: 'bash'
dir: 'src'
args:
- '-c'
- |
set -e
# Install Node.js 24 (nodesource setup script also runs apt-get update)
curl -fsSL https://deb.nodesource.com/setup_24.x | bash -
apt-get install -y nodejs

# Install Python dependencies
pip install --quiet -r requirements.txt

# Install Node dependencies (uses package-lock.json for reproducibility)
npm ci

# Start the web server in the background (required for URL tests)
python main.py background &
sleep 3

# Generate all chapters
npm run generate

# Run Python unit tests
npm run pytest

# Run full URL test suite against the running server
npm run test

# ─────────────────────────────────────────────────────────────────────────
# Step 2: Update timestamps then generate PDF ebooks.
# Prince fetches pages from a running localhost server, so the Python server
# is re-started here. Chapters written to /workspace/src in step 1 are
# served directly; npm install is skipped (node_modules already present).
# ─────────────────────────────────────────────────────────────────────────
- name: 'python:3.12'
id: 'generate-ebooks'
entrypoint: 'bash'
dir: 'src'
args:
- '-c'
- |
set -e
apt-get update -qq

# Install Node.js 20
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt-get install -y nodejs

# Update static-asset cache-busting hashes before deploying
npm run timestamps

# Install CJK fonts for multilingual ebooks
apt-get install -y fonts-ipafont-gothic fonts-arphic-uming fonts-unfonts-core wget

# Install pdftk (ebook post-processing)
apt-get install -y pdftk

# Download and install Prince PDF generator
wget -q "https://www.princexml.com/download/${_PRINCE_PACKAGE}" -P /tmp
apt-get install -y "/tmp/${_PRINCE_PACKAGE}"

# Install Python dependencies (needed to run the web server)
pip install --quiet -r requirements.txt

# Re-start the web server so Prince can fetch pages from localhost
python main.py background &
sleep 3

# Generate PDF ebooks
mkdir -p static/pdfs
npm run ebooks

# ─────────────────────────────────────────────────────────────────────────
# Step 3: Deploy to Google App Engine.
# app.yaml is read from /workspace/src (dir: src).
# App Engine version labels must start with a letter, so SHORT_SHA is
# prefixed: e.g. a1b2c3d → deploy-a1b2c3d.
# ─────────────────────────────────────────────────────────────────────────
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
id: 'deploy'
entrypoint: 'bash'
dir: 'src'
args:
- '-c'
- |
set -e
VERSION="deploy-${SHORT_SHA}"
echo "Deploying version: ${VERSION}"
gcloud app deploy \
--project webalmanac \
--version="${VERSION}" \
--stop-previous-version \
--quiet

# ─────────────────────────────────────────────────────────────────────────
# Step 4: Upload generated ebooks to GCS.
# Uses nullglob so missing PDFs produce a warning rather than an error.
# ─────────────────────────────────────────────────────────────────────────
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
id: 'upload-ebooks'
entrypoint: 'bash'
args:
- '-c'
- |
set -e
shopt -s nullglob
pdfs=(/workspace/src/static/pdfs/web_almanac_*.pdf)
if [[ ${#pdfs[@]} -gt 0 ]]; then
gsutil -m cp "${pdfs[@]}" gs://httparchive/almanac/ebooks/
echo "Uploaded ${#pdfs[@]} PDF(s) to GCS"
else
echo "Warning: no ebooks found to upload"
fi

# Total timeout covers: ~10 min build/test + ~30 min ebook generation +
# ~10 min deploy + ~5 min GCS upload.
timeout: '3600s'
Loading