-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
build: setup preview builds for dev-app (#23825)
* build: setup preview builds for dev-app Sets up preview builds for the dev-app. Whenever the `dev-app preview` label is applied to pull requests, a Github action will build the dev-app using RBE and deploy it to a preview channel within a Firebase project. The deployment and building is split up into two individual workflows to guarantee a secure exeuction of these steps. This follows the concept as outlined in https://securitylab.github.com/research/github-actions-preventing-pwn-requests/. In the future, we can try extracting some of this logic into a common tool in the dev-infra repository.. allowing preview builds to be used for other things, or in other repositories as well (or switching AIO away from the rather-complicated docker preview build setup). * fixup! build: setup preview builds for dev-app Address feedback * fixup! build: setup preview builds for dev-app Update old links (cherry picked from commit 7ec0139)
- Loading branch information
1 parent
d8c84d6
commit 37c39ed
Showing
8 changed files
with
187 additions
and
23 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
name: "Installing Yarn dependencies" | ||
description: "Installs the dependencies using Yarn" | ||
|
||
runs: | ||
using: "composite" | ||
steps: | ||
- uses: actions/cache@v2 | ||
with: | ||
path: | | ||
**/node_modules | ||
# Cache key. Whenever the postinstall patches change, the cache needs to be invalidated. | ||
# If just the `yarn.lock` file changes, the most recent cache can be restored though. | ||
# See: https://docs.github.com/en/actions/guides/caching-dependencies-to-speed-up-workflows#example-using-the-cache-action. | ||
key: v2-${{hashFiles('tools/postinstall/apply-patches.js')}}-${{hashFiles('yarn.lock')}} | ||
restore-keys: v2-${{hashFiles('tools/postinstall/apply-patches.js')}}- | ||
|
||
- run: yarn install --frozen-lockfile --non-interactive | ||
shell: bash |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# This workflow builds the dev-app for pull requests when a certain label is applied. | ||
# The actual deployment happens as part of a dedicated second workflow to avoid security | ||
# issues where the building would otherwise occur in an authorized context where secrets | ||
# could be leaked. More details can be found here: | ||
|
||
# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/. | ||
|
||
name: Build dev-app for deployment | ||
|
||
on: | ||
pull_request: | ||
types: [synchronize, labeled] | ||
|
||
jobs: | ||
dev-app-build: | ||
runs-on: ubuntu-latest | ||
# We only want to build and deploy the dev-app if the `dev-app preview` label has been | ||
# added, or if the label is already applied and new changes have been made in the PR. | ||
if: | | ||
(github.event.action == 'labeled' && github.event.label.name == 'dev-app preview') || | ||
(github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'dev-app preview')) | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: ./.github/actions/yarn-install | ||
|
||
- run: ./scripts/bazel/setup-remote-execution.sh | ||
env: | ||
GCP_DECRYPT_TOKEN: angular | ||
|
||
# Build the web package. Note that we also need to make the Github environment | ||
# variables available so that the RBE is configured. | ||
- name: Building dev-app | ||
run: | | ||
source ${GITHUB_ENV} | ||
bazel build //src/dev-app:web_package --symlink_prefix=dist/ | ||
# Prepare the workflow artifact that is available for the deploy workflow. We store the pull | ||
# request number and SHA in a file that can be read by the deploy workflow. This is necessary | ||
# so that the deploy workflow can create a comment on the PR that triggered the deploy. | ||
- run: | | ||
mkdir -p dist/devapp | ||
cp -R dist/bin/src/dev-app/web_package/* dist/devapp | ||
echo ${{github.event.pull_request.number}} > dist/devapp/pr_number | ||
echo ${{github.event.pull_request.head.sha}} > dist/devapp/pr_sha | ||
# Upload the generated dev-app archive. | ||
- uses: actions/upload-artifact@v2 | ||
with: | ||
name: devapp | ||
path: dist/devapp |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# This workflow runs whenever the dev-app build workflow has completed. Deployment happens | ||
# as part of a dedicated second workflow to avoid security issues where the building would | ||
# otherwise occur in an authorized context where secrets could be leaked. | ||
# | ||
# More details can be found here: | ||
# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/. | ||
|
||
name: Deploying dev-app to Firebase previews | ||
|
||
on: | ||
workflow_run: | ||
workflows: [Build dev-app for deployment] | ||
types: [completed] | ||
|
||
jobs: | ||
deploy-dev-app: | ||
runs-on: ubuntu-latest | ||
if: ${{ github.event.workflow_run.conclusion == 'success' }} | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: ./.github/actions/yarn-install | ||
|
||
- name: 'Download artifact from build job' | ||
run: | | ||
./scripts/github/fetch-workflow-artifact.mjs ${{secrets.GITHUB_TOKEN}} \ | ||
${{github.event.workflow_run.id}} devapp > devapp.zip | ||
- name: Extracting workflow artifact into Firebase public directory. | ||
run: | | ||
mkdir -p dist/dev-app-web-pkg | ||
unzip devapp.zip -d dist/dev-app-web-pkg | ||
- name: Extracting pull request from extracted workflow artifact. | ||
id: pr_info | ||
run: | | ||
echo "::set-output name=number::$(cat ./dist/dev-app-web-pkg/pr_number)" | ||
echo "::set-output name=sha::$(cat ./dist/dev-app-web-pkg/pr_sha)" | ||
- uses: FirebaseExtended/action-hosting-deploy@v0 | ||
id: deploy | ||
with: | ||
repoToken: '${{secrets.GITHUB_TOKEN}}' | ||
firebaseServiceAccount: '${{secrets.FIREBASE_PREVIEW_SERVICE_TOKEN}}' | ||
expires: 20d | ||
projectId: angular-components-test | ||
channelId: pr-${{steps.pr_info.outputs.number}}-${{steps.pr_info.outputs.sha}} | ||
|
||
- uses: marocchino/sticky-pull-request-comment@v2 | ||
with: | ||
message: | | ||
Deployed dev-app to: ${{ steps.deploy.outputs.details_url }} | ||
number: ${{ steps.pr_info.outputs.number }} |
File renamed without changes.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#!/bin/bash | ||
|
||
# The script should immediately exit if any command in the script fails. | ||
set -e | ||
|
||
if [[ -z "${GCP_DECRYPT_TOKEN}" ]]; then | ||
echo "Please specify the \"GCP_DECRYPT_TOKEN\" environment variable when setting up remote " \ | ||
"execution" | ||
exit 1 | ||
fi | ||
|
||
# Decode the GCP token that is needed to authenticate the Bazel remote execution. | ||
openssl aes-256-cbc -d -in scripts/bazel/gcp_token -md md5 -k ${GCP_DECRYPT_TOKEN} \ | ||
-out $HOME/.gcp_credentials | ||
|
||
# Set the "GOOGLE_APPLICATION_CREDENTIALS" environment variable. It should point to the GCP credentials | ||
# file. Bazel will then automatically picks up the credentials from that variable. | ||
# https://docs.bazel.build/versions/main/command-line-reference.html#flag--google_default_credentials | ||
# https://cloud.google.com/docs/authentication/production. | ||
if [[ ! -z "${BASH_ENV}" ]]; then | ||
# CircleCI uses the `BASH_ENV` variable for environment variables. | ||
echo "export GOOGLE_APPLICATION_CREDENTIALS=${HOME}/.gcp_credentials" >> ${BASH_ENV} | ||
elif [[ ! -z "${GITHUB_ENV}" ]]; then | ||
# Github actions use the `GITHUB_ENV` variable for environment variables. | ||
echo "GOOGLE_APPLICATION_CREDENTIALS=${HOME}/.gcp_credentials" >> ${GITHUB_ENV} | ||
fi | ||
|
||
# Update the project Bazel configuration to always use remote execution. | ||
echo "build --config=remote" >> .bazelrc |
This file was deleted.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#!/usr/bin/env node | ||
|
||
/** | ||
* Fetches a specified artifact by name from the given workflow and writes | ||
* the downloaded zip file to the stdout. | ||
* | ||
* Command line usage: | ||
* ./fetch-workflow-artifact.js <gh-token> <workflow-id> <artifact-name> | ||
*/ | ||
|
||
import octokit from '@octokit/rest'; | ||
|
||
async function main() { | ||
const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/', 2); | ||
const [token, workflowId, artifactName] = process.argv.slice(2); | ||
const github = new octokit.Octokit({auth: token}); | ||
const artifacts = await github.actions.listWorkflowRunArtifacts({ | ||
owner, | ||
repo, | ||
run_id: workflowId, | ||
}); | ||
|
||
const matchArtifact = artifacts.data.artifacts.find( | ||
artifact => artifact.name === artifactName, | ||
); | ||
|
||
const download = await github.actions.downloadArtifact({ | ||
owner, | ||
repo, | ||
artifact_id: matchArtifact.id, | ||
archive_format: 'zip', | ||
}); | ||
|
||
process.stdout.write(Buffer.from(download.data)); | ||
} | ||
|
||
await main(); |