diff --git a/.gcloudignore b/.gcloudignore new file mode 100644 index 00000000..917f247e --- /dev/null +++ b/.gcloudignore @@ -0,0 +1,5 @@ +.git +_site +node_modules +vendor +travis diff --git a/.gitmodules b/.gitmodules index 323c1783..5e1e312a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,6 +4,3 @@ [submodule "ndt"] path = ndt url = https://github.com/m-lab/ndt -[submodule "travis"] - path = travis - url = https://github.com/m-lab/travis.git diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 710cf473..00000000 --- a/.travis.yml +++ /dev/null @@ -1,58 +0,0 @@ -dist: noble -language: ruby -rvm: - - 3.1 - -env: - global: - - NOKOGIRI_USE_SYSTEM_LIBRARIES=true - - NODE_VERSION=v14 - -before_install: - - gem install bundler:2.3.9 - - rvm use 3.1 - - gem install dpl - -script: - - set -e - - "$TRAVIS_BUILD_DIR/travis/install_gcloud.sh" - - sudo apt-get install -y python3-pip jupyter jupyter-nbconvert - #- sudo -H python3 -m pip install --upgrade setuptools pip - - nvm install $NODE_VERSION - - npm install -g firebase-tools@11.30.0 - - "./_tests/travis-checks --quick" - -deploy: - # Separate deployments to various places based on branch and push type - ## - sandbox - - provider: script - edge: true - cleanup: false - script: - "$TRAVIS_BUILD_DIR/travis/activate_service_account.sh SERVICE_ACCOUNT_mlab_sandbox - && gsutil -h 'Cache-Control:no-store' -m cp -r $TRAVIS_BUILD_DIR/_site/* gs://website.mlab-sandbox.measurementlab.net/" - on: - repo: m-lab/website - all_branches: true - condition: "$TRAVIS_BRANCH == sandbox-* && $TRAVIS_EVENT_TYPE == push" - - ## - staging - - provider: script - edge: true - cleanup: false - script: - "$TRAVIS_BUILD_DIR/travis/activate_service_account.sh SERVICE_ACCOUNT_mlab_staging - && gsutil -h 'Cache-Control:no-store' -m cp -r $TRAVIS_BUILD_DIR/_site/* gs://website.mlab-staging.measurementlab.net/" - on: - repo: m-lab/website - all_branches: true - condition: "$TRAVIS_BRANCH == main && $TRAVIS_EVENT_TYPE == push" - - ## - production - - provider: script - edge: true - cleanup: false - script: "$TRAVIS_BUILD_DIR/firebase-deploy.sh" - on: - repo: m-lab/website - tags: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3523ea0f..558c3116 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ This document outlines setup, standards, and practices for contributing to the M-Lab website. Content is written in markdown, and Jekyll applies templates -and formatting when generating the final static site. We use Travis-ci to test +and formatting when generating the final static site. We use Google Cloud Build to test site builds and deployments, previewing branches matching the pattern `sandbox-*` @@ -39,13 +39,13 @@ Docker builds. Remove locally installed dependencies if this happens to you. ## Publication Process The website publication process uses a combination of continuous integration -using Travis CI, pull requests, code review and release tagging. +using Google Cloud Build, pull requests, code review and release tagging. -The file `.travis.tml` is configured to do the following actions: +The file `cloudbuild.yaml` is run by per-project Cloud Build triggers to do the following actions: * When a branch matching the pattern `sandbox-*` is pushed: - * Travis CI builds the site and publishes it to the GCS bucket + * Cloud Build builds the site and publishes it to the GCS bucket `gs://website.mlab-sandbox.measurementlab.net` in the project `mlab-sandbox` * Content can then be previewed at @@ -53,7 +53,7 @@ The file `.travis.tml` is configured to do the following actions: * When a pull request is approved and merged into the `main` branch: - * Travis CI builds the site and publishes to the GCS bucket + * Cloud Build builds the site and publishes to the GCS bucket `gs://website.mlab-staging.measurementlab.net` in the project `mlab-staging` * Content can then be previewed at @@ -61,7 +61,7 @@ The file `.travis.tml` is configured to do the following actions: * When a repository owner tags a release in Github: - * Travis CI builds the site and publishes it to a Google Firebase project + * Cloud Build builds the site and publishes it to a Google Firebase project * The [production website][website-prod] is then updated with the content from this release @@ -132,11 +132,11 @@ View the generated site by visiting: [http://localhost:4000/](http://localhost:4 | notebooks | Contains Jupyter notebooks to be included on pages or posts. | | publications | Contains all the pdfs and docs that are included or linked in the site. | | static | Contains additional static content. | -| travis | Submodule for [m-lab/travis](https://github.com/m-lab/travis) to support deployment automation in Travis CI. | -| .firebaserc | Defines the Firebase project and hosting. Used by Travis CI to automate publishing of tagged releases. | +| .firebaserc | Defines the Firebase project and hosting. Used by Cloud Build to publish tagged releases. | | .gitignore | Defines which files and file patterns should be excluded from Git commits. | | .gitmodules | Defines the Git submodules used in this repo. | -| .travis.yml | Travis CI build and deployment configurations. | +| cloudbuild.yaml | Google Cloud Build build and deployment configuration. | +| Dockerfile.build | Builder image Cloud Build uses to build the site. | | CONTRIBUTING.md | Provides onboarding details for new contributors. | | Dockerfile | Defines the Docker container for building and previewing the site locally. | | LICENSE | Software license for the code in this repository. | diff --git a/Dockerfile.build b/Dockerfile.build new file mode 100644 index 00000000..d42b1331 --- /dev/null +++ b/Dockerfile.build @@ -0,0 +1,28 @@ +# Builder image for the M-Lab website. +# +# Bundles the full toolchain the Jekyll build needs, replacing what Travis used +# to install inline: +# * Ruby 3.1 + bundler -> jekyll build +# * Node 18 -> js/libs/r.js RequireJS optimizer (minified app.js) +# * jupyter + nbconvert -> the jekyll-jupyter-notebook plugin shells out to +# `jupyter nbconvert` while rendering .ipynb pages +# * firebase-tools -> production deploy to Firebase Hosting (mlab-oti) +# * gcloud/gsutil come from dedicated cloud-builders steps, not this image. +FROM ruby:3.1-slim-bookworm + +ENV DEBIAN_FRONTEND=noninteractive + +# build-essential + the -dev headers are needed to compile native gems +# (openssl, nokogiri, sassc, ...) that Travis's fuller base image already had. +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential ca-certificates curl git pkg-config \ + libssl-dev zlib1g-dev libyaml-dev libxml2-dev libxslt1-dev \ + python3 python3-pip \ + && curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \ + && apt-get install -y --no-install-recommends nodejs \ + && pip3 install --no-cache-dir --break-system-packages jupyter nbconvert \ + && npm install -g firebase-tools@13 \ + && gem install bundler:2.3.9 \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +WORKDIR /workspace diff --git a/README.md b/README.md index db22e78a..84b91d81 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ This is the source code of the Measurement Lab website built using [Jekyll](http://jekyllrb.com). -Current Build Status is: [![Build Status](https://secure.travis-ci.org/m-lab/website.png?branch=master)](http://travis-ci.org/m-lab/website) ## Contributing diff --git a/_config.yml b/_config.yml index 8bad7cbe..fb32d096 100644 --- a/_config.yml +++ b/_config.yml @@ -29,7 +29,6 @@ exclude: - _scripts - _site - vendor - - travis # Markdown settings markdown: kramdown diff --git a/cloudbuild.yaml b/cloudbuild.yaml new file mode 100644 index 00000000..0f7732c0 --- /dev/null +++ b/cloudbuild.yaml @@ -0,0 +1,70 @@ +# Build + deploy for the M-Lab website, replacing .travis.yml. +# +# One config, three per-project triggers (see repo docs / gcloud commands): +# * mlab-sandbox trigger: push to ^sandbox-.*$ -> GCS website.mlab-sandbox... +# * mlab-staging trigger: push to ^main$ -> GCS website.mlab-staging... +# * mlab-oti trigger: any tag .* -> Firebase Hosting +# +# Each deploy step is guarded by $$PROJECT_ID so the same file is safe in every +# project: a trigger only ever runs the deploy that matches its project. Deploys +# authenticate as the project's Cloud Build service account -- no service +# account key env vars (the old SERVICE_ACCOUNT_* secrets are no longer needed). +timeout: 1800s + +options: + machineType: 'N1_HIGHCPU_8' + env: + # Expose the substituted project id to steps as a real env var. Referenced in + # scripts as $$PROJECT_ID so the shell (not Cloud Build) expands it. + - PROJECT_ID=$PROJECT_ID + +steps: +# 1. Build the toolchain image (Ruby + Node + Jupyter + Firebase CLI). +- id: build-image + name: gcr.io/cloud-builders/docker + args: ['build', '-t', 'website-builder', '-f', 'Dockerfile.build', '.'] + +# 2. Build the Jekyll site into _site/. Reuses the exact build logic that Travis +# ran (r.js optimize -> rewrite basejs -> jekyll build), living in +# _tests/travis-checks so build and deploy stay in one place. +- id: build-site + name: website-builder + entrypoint: bash + args: + - -c + - | + set -euxo pipefail + bundle install + ./_tests/travis-checks --quick + +# 3. sandbox + staging: publish _site/ to the per-project GCS bucket. +- id: deploy-gcs + name: gcr.io/cloud-builders/gsutil + entrypoint: bash + args: + - -c + - | + set -euo pipefail + case "$$PROJECT_ID" in + mlab-sandbox|mlab-staging) + gsutil -h 'Cache-Control:no-store' -m cp -r _site/* \ + "gs://website.$$PROJECT_ID.measurementlab.net/" + ;; + *) + echo "Not a GCS-deploy project ($$PROJECT_ID); skipping." + ;; + esac + +# 4. production: deploy _site/ to Firebase Hosting (mlab-oti only). +- id: deploy-firebase + name: website-builder + entrypoint: bash + args: + - -c + - | + set -euo pipefail + if [ "$$PROJECT_ID" = "mlab-oti" ]; then + firebase deploy --only hosting --project mlab-oti --non-interactive + else + echo "Not the production project ($$PROJECT_ID); skipping Firebase deploy." + fi diff --git a/firebase-deploy.sh b/firebase-deploy.sh deleted file mode 100755 index 4f377837..00000000 --- a/firebase-deploy.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -set -e -tmpdir=$( mktemp -d ) -echo "${SERVICE_ACCOUNT_mlab_oti}" > $tmpdir/sa.json - -set -x -export GOOGLE_APPLICATION_CREDENTIALS=$tmpdir/sa.json -firebase use mlab-oti && firebase deploy --only hosting diff --git a/travis b/travis deleted file mode 160000 index b64dca69..00000000 --- a/travis +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b64dca69cfb6d99f93b306c620f5a635ccccd980