[Snyk] Security upgrade next from 11.1.4 to 13.5.0 #185
This file contains 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: Staging - Build and Deploy PR (fast and private-only) | |
# **What it does**: Builds and deploys PRs to staging but ONLY for docs-internal | |
# **Why we have it**: Most PRs are made on the private repo. Let's make those extra fast if we can worry less about security. | |
# **Who does it impact**: All staff. | |
# This whole workflow is only guaranteed to be secure in the *private | |
# repo* and because we repo-sync these files over the to the public one, | |
# IT'S IMPORTANT THAT THIS WORKFLOW IS ONLY ENABLED IN docs-internal! | |
on: | |
# The advantage of 'pull_request' over 'pull_request_target' is that we | |
# can make changes to this file and test them in a pull request, instead | |
# of relying on landing it in 'main' first. | |
# From a security point of view, its arguably safer this way because | |
# unlike 'pull_request_target', these only have secrets if the pull | |
# request creator has permission to access secrets. | |
pull_request: | |
permissions: | |
actions: read | |
contents: read | |
deployments: write | |
pull-requests: read | |
statuses: write | |
# This allows a subsequently queued workflow run to interrupt previous runs | |
concurrency: | |
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}' | |
cancel-in-progress: true | |
jobs: | |
build-and-deploy-pr: | |
# Important. This whole file is only supposed to run in the PRIVATE repo. | |
if: ${{ github.repository == 'github/docs-internal' }} | |
# The assumption here is that self-hosted is faster (e.g CPU power) | |
# that the regular ones. And it matters in this workflow because | |
# we do heavy CPU stuff with `npm run build` and `tar` | |
# runs-on: ubuntu-latest | |
runs-on: self-hosted | |
timeout-minutes: 5 | |
steps: | |
- name: Check out repo | |
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 | |
with: | |
lfs: 'true' | |
# To prevent issues with cloning early access content later | |
persist-credentials: 'false' | |
- name: Check out LFS objects | |
run: git lfs checkout | |
- name: Setup node | |
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561 | |
with: | |
node-version: 16.13.x | |
cache: npm | |
- name: Install dependencies | |
run: npm ci | |
- name: Cache nextjs build | |
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed | |
with: | |
path: .next/cache | |
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }} | |
- name: Build | |
run: npm run build | |
- name: Clone early access | |
run: node script/early-access/clone-for-build.js | |
env: | |
DOCUBOT_REPO_PAT: ${{ secrets.DOCUBOT_REPO_PAT }} | |
GIT_BRANCH: ${{ github.head_ref || github.ref }} | |
- name: Create a Heroku build source | |
id: build-source | |
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d | |
env: | |
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }} | |
with: | |
script: | | |
const { owner, repo } = context.repo | |
if (owner !== 'github') { | |
throw new Error(`Repository owner must be 'github' but was: ${owner}`) | |
} | |
if (repo !== 'docs-internal') { | |
throw new Error(`Repository name must be 'docs-internal' but was: ${repo}`) | |
} | |
const Heroku = require('heroku-client') | |
const heroku = new Heroku({ token: process.env.HEROKU_API_TOKEN }) | |
try { | |
const { source_blob: sourceBlob } = await heroku.post('/sources') | |
const { put_url: uploadUrl, get_url: downloadUrl } = sourceBlob | |
core.setOutput('upload_url', uploadUrl) | |
core.setOutput('download_url', downloadUrl) | |
} catch (error) { | |
if (error.statusCode === 503) { | |
console.error('💀 Heroku may be down! Please check its Status page: https://status.heroku.com/') | |
} | |
throw error | |
} | |
- name: Remove development-only dependencies | |
run: npm prune --production | |
- name: Remove all npm scripts | |
run: npm pkg delete scripts | |
- name: Set npm script for Heroku build to noop | |
run: npm set-script heroku-postbuild "echo 'Application was pre-built!'" | |
- name: Delete heavy things we won't need deployed | |
run: | | |
# The dereferenced file is not used in runtime once the | |
# decorated file has been created from it. | |
rm -rf lib/rest/static/dereferenced | |
# Translations are never tested in Staging builds | |
# but let's keep the empty directory. | |
rm -rf translations | |
mkdir translations | |
# Delete all the big search indexes that are NOT English (`*-en-*`) | |
pushd lib/search/indexes | |
ls | grep -ve '\-en\b' | xargs rm | |
popd | |
# Note! Some day it would be nice to be able to delete | |
# all the heavy assets because they bloat the tarball. | |
# But it's not obvious how to test it then. For now, we'll have | |
# to accept that every staging build has a copy of the images. | |
# The assumption here is that a staging build will not | |
# need these legacy redirects. Only the redirects from | |
# front-matter will be at play. | |
# These static redirects json files are notoriously large | |
# and they make the tarball unnecessarily large. | |
echo '[]' > lib/redirects/static/archived-frontmatter-fallbacks.json | |
echo '{}' > lib/redirects/static/developer.json | |
echo '{}' > lib/redirects/static/archived-redirects-from-213-to-217.json | |
# This will turn every `lib/**/static/*.json` into | |
# an equivalent `lib/**/static/*.json.br` file. | |
# Once the server starts, it'll know to fall back to reading | |
# the `.br` equivalent if the `.json` file isn't present. | |
node .github/actions-scripts/compress-large-files.js | |
- name: Make the tarball for Heroku | |
run: | | |
# We can't delete the .next/cache directory from the workflow | |
# because it's needed for caching, but we can at least exclude it | |
# from the tarball. Then it can be cached but not weigh down the | |
# tarball we intend to deploy. | |
tar -zc --exclude=.next/cache --file=app.tar.gz \ | |
node_modules/ \ | |
.next/ \ | |
assets/ \ | |
content/ \ | |
data/ \ | |
includes/ \ | |
lib/ \ | |
middleware/ \ | |
translations/ \ | |
server.mjs \ | |
package*.json \ | |
.npmrc \ | |
feature-flags.json \ | |
next.config.js \ | |
app.json \ | |
Procfile | |
du -sh app.tar.gz | |
# See: https://devcenter.heroku.com/articles/build-and-release-using-the-api#sources-endpoint | |
- name: Upload to the Heroku build source | |
env: | |
UPLOAD_URL: ${{ steps.build-source.outputs.upload_url }} | |
run: | | |
curl "$UPLOAD_URL" \ | |
-X PUT \ | |
-H 'Content-Type:' \ | |
--data-binary @app.tar.gz | |
# 'npm install' is faster than 'npm ci' because it only needs to | |
# *append* what's missing from ./node_modules/ | |
- name: Re-install dependencies so we get devDependencies back | |
run: npm install --no-audit --no-fund --only=dev | |
- name: Deploy | |
id: deploy | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }} | |
HYDRO_ENDPOINT: ${{ secrets.HYDRO_ENDPOINT }} | |
HYDRO_SECRET: ${{ secrets.HYDRO_SECRET }} | |
PR_URL: ${{ github.event.pull_request.html_url }} | |
SOURCE_BLOB_URL: ${{ steps.build-source.outputs.download_url }} | |
ALLOWED_POLLING_FAILURES_PER_PHASE: '15' | |
RUN_ID: ${{ github.run_id }} | |
run: .github/actions-scripts/staging-deploy.js |