Skip to content

Commit

Permalink
DEVPROD-5375: Add staging and beta deploy tasks to Evergreen (#177)
Browse files Browse the repository at this point in the history
  • Loading branch information
sophstad authored Jun 17, 2024
1 parent b0e9994 commit 837d61b
Show file tree
Hide file tree
Showing 26 changed files with 381 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .evergreen/attach.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ functions:
aws_key: ${AWS_ACCESS_KEY_ID}
aws_secret: ${AWS_SECRET_ACCESS_KEY}
aws_session_token: ${AWS_SESSION_TOKEN}
local_file: "ui/${app_dir}/build/source_map.html"
local_file: "ui/${app_dir}/dist/source_map.html"
remote_file: ${build_variant}/${task_id}/${execution}/source_map.html
bucket: evg-bucket-evergreen-ui
content_type: text/html
Expand Down
96 changes: 96 additions & 0 deletions .evergreen/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
functions:
setup-credentials:
command: shell.exec
params:
working_dir: ui/apps/${app_to_deploy}
env:
BUCKET: ${bucket_arg}
NEW_RELIC_ACCOUNT_ID: ${NEW_RELIC_ACCOUNT_ID}
NEW_RELIC_LICENSE_KEY: ${NEW_RELIC_LICENSE_KEY}
NEW_RELIC_TRUST_KEY: ${NEW_RELIC_TRUST_KEY}
PARSLEY_NEW_RELIC_AGENT_ID: ${PARSLEY_NEW_RELIC_AGENT_ID}
PARSLEY_NEW_RELIC_APPLICATION_ID: ${PARSLEY_NEW_RELIC_APPLICATION_ID}
PARSLEY_SENTRY_AUTH_TOKEN: ${PARSLEY_SENTRY_AUTH_TOKEN}
REACT_APP_PARSLEY_SENTRY_DSN: ${REACT_APP_PARSLEY_SENTRY_DSN}
REACT_APP_SPRUCE_SENTRY_DSN: ${REACT_APP_SPRUCE_SENTRY_DSN}
SPRUCE_NEW_RELIC_AGENT_ID: ${SPRUCE_NEW_RELIC_AGENT_ID}
SPRUCE_NEW_RELIC_APPLICATION_ID: ${SPRUCE_NEW_RELIC_APPLICATION_ID}
SPRUCE_SENTRY_AUTH_TOKEN: ${SPRUCE_SENTRY_AUTH_TOKEN}
script: |
${PREPARE_SHELL}
PWD=$(pwd) yarn ts-node -e "import {setupCredentials} from '@evg-ui/deploy-utils'; setupCredentials(\"$PWD\", \"${target}\");"
deploy:
command: shell.exec
params:
working_dir: ui/apps/${app_to_deploy}
env:
BUCKET: ${bucket_arg}
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
AWS_SESSION_TOKEN: ${AWS_SESSION_TOKEN}
script: |
${PREPARE_SHELL}
yarn env-cmd -e ${target} ts-node -e "import {deployRemote} from '@evg-ui/deploy-utils'; deployRemote();"
tasks:
- name: deploy-parsley-staging
commands:
- func: setup-credentials
vars:
app_to_deploy: parsley
bucket_arg: ${parsley_bucket_staging}
target: staging
- func: symlink
vars:
app_dir: apps/parsley
- func: deploy
vars:
app_to_deploy: parsley
bucket_arg: ${parsley_bucket_staging}
target: staging
- name: deploy-parsley-beta
commands:
- func: setup-credentials
vars:
app_to_deploy: parsley
bucket_arg: ${parsley_bucket_beta}
target: beta
- func: symlink
vars:
app_dir: apps/parsley
- func: deploy
vars:
app_to_deploy: parsley
bucket_arg: ${parsley_bucket_beta}
target: beta
- name: deploy-spruce-staging
commands:
- func: setup-credentials
vars:
app_to_deploy: spruce
bucket_arg: ${spruce_bucket_staging}
target: staging
- func: symlink
vars:
app_dir: apps/spruce
- func: deploy
vars:
app_to_deploy: spruce
bucket_arg: ${spruce_bucket_staging}
target: staging
- name: deploy-spruce-beta
commands:
- func: setup-credentials
vars:
app_to_deploy: spruce
bucket_arg: ${spruce_bucket_beta}
target: beta
- func: symlink
vars:
app_dir: apps/spruce
- func: deploy
vars:
app_to_deploy: spruce
bucket_arg: ${spruce_bucket_beta}
target: beta
34 changes: 33 additions & 1 deletion .evergreen/evergreen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ post:
- func: attach-test-results

include:
- filename: .evergreen/shared.yml
- filename: .evergreen/attach.yml
- filename: .evergreen/deploy.yml
- filename: .evergreen/generate.yml
- filename: .evergreen/shared.yml

buildvariants:
- name: spruce
Expand Down Expand Up @@ -114,14 +115,45 @@ buildvariants:
- name: test
- name: type_check

- name: deploy-utils
display_name: Deploy Utils
expansions:
app_dir: packages/deploy-utils
goroot: /opt/golang/go1.20
mongodb_tools_url: https://fastdl.mongodb.org/tools/db/mongodb-database-tools-ubuntu2204-x86_64-100.8.0.tgz
mongodb_url_2204: https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2204-7.0.2.tgz
mongosh_url_2204: https://downloads.mongodb.com/compass/mongosh-2.0.2-linux-x64.tgz
node_version: 20.10.0
run_on:
- ubuntu2204-large
- ubuntu2204-small
tasks:
- name: lint
- name: test
- name: type_check

- name: generator
display_name: Generator
allowed_requesters: ["github_pr"]
# Omit node_version expansion so that yarn-install fails to save time.
run_on:
- ubuntu2204-small
tasks:
- generate-tasks

- name: deploy
display_name: Deploys
allowed_requesters: ["patch"]
expansions:
node_version: 20.10.0
run_on:
- ubuntu2204-large
tasks:
- name: deploy-parsley-beta
- name: deploy-parsley-staging
- name: deploy-spruce-beta
- name: deploy-spruce-staging

parameters:
- key: cypress_spec
value: cypress/integration/**/*
Expand Down
1 change: 0 additions & 1 deletion .evergreen/generate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ functions:

tasks:
- name: generate-tasks
allowed_requesters: ["github_pr"]
commands:
- func: run-generate-tasks
- command: generate.tasks
Expand Down
1 change: 1 addition & 0 deletions .evergreen/scripts/generate-tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const Tasks = {
// Enumerate each task in a build variant that can run as part of a PR.
// It would be nice to use tags for this, but Evergreen does not reevaluate tags as part of generate.tasks.
const TASK_MAPPING = {
"deploy-utils": [Tasks.Lint, Tasks.Test, Tasks.TypeCheck],
lib: [
Tasks.Lint,
Tasks.Snapshots,
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
node_modules

.env-cmdrc.json

# artifacts
bin
build
Expand Down
1 change: 1 addition & 0 deletions apps/parsley/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"@apollo/client": "3.10.4",
"@emotion/react": "11.11.0",
"@emotion/styled": "11.11.5",
"@evg-ui/deploy-utils": "*",
"@evg-ui/lib": "*",
"@leafygreen-ui/badge": "8.0.2",
"@leafygreen-ui/button": "21.0.6",
Expand Down
2 changes: 1 addition & 1 deletion apps/parsley/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export default defineConfig({
checker({ typescript: true }),
// Bundle analyzer
visualizer({
filename: "build/source_map.html",
filename: "dist/source_map.html",
template: "treemap",
}),
sentryVitePlugin({
Expand Down
3 changes: 2 additions & 1 deletion apps/spruce/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"build:staging": "env-cmd -e staging yarn build",
"build": "GIT_SHA=`git rev-parse HEAD` APP_VERSION=$npm_package_version vite build",
"check-types": "tsc -p tsconfig.json --noEmit",
"clean": "rm -rf node_modules && rm -rf build && yarn install",
"clean": "rm -rf node_modules && rm -rf dist && yarn install",
"codegen": "graphql-codegen --config codegen.ts",
"cy:open": "yarn evg-db-ops --reseed-and-dump; cypress open",
"cy:run": "cypress run",
Expand Down Expand Up @@ -54,6 +54,7 @@
"@emotion/css": "11.11.0",
"@emotion/react": "11.11.0",
"@emotion/styled": "11.11.0",
"@evg-ui/deploy-utils": "*",
"@evg-ui/lib": "*",
"@leafygreen-ui/badge": "8.0.2",
"@leafygreen-ui/banner": "7.0.4",
Expand Down
2 changes: 1 addition & 1 deletion apps/spruce/scripts/deploy/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

echo "Deploying to S3"

if ! aws s3 sync build/ s3://"${BUCKET}"/ --acl public-read --follow-symlinks --delete --exclude .env-cmdrc.json; then
if ! aws s3 sync dist/ s3://"${BUCKET}"/ --acl public-read --follow-symlinks --delete --exclude .env-cmdrc.json; then
echo "Deployment to S3 failed"
exit 1
else
Expand Down
4 changes: 2 additions & 2 deletions apps/spruce/scripts/deploy/utils/deploy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ const runDeploy = () => {
console.log("Building");
execSync("yarn build:prod", { stdio: "inherit" });
console.log("Build complete");
console.log("Saving current commit in build/commit.txt");
console.log("Saving current commit in dist/commit.txt");
const currentCommit = getCurrentCommit();
execSync(`echo ${currentCommit} > build/commit.txt`, {
execSync(`echo ${currentCommit} > dist/commit.txt`, {
stdio: "inherit",
});
console.log("Deploying to production");
Expand Down
2 changes: 1 addition & 1 deletion apps/spruce/scripts/prod-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const server = http.createServer((request, response) => {
return proxy.web(request, response, { target: "http://localhost:9090" });
}
return handler(request, response, {
public: path.resolve(__dirname, "../build"),
public: path.resolve(__dirname, "../dist"),
rewrites: [
{
source: "**",
Expand Down
7 changes: 3 additions & 4 deletions apps/spruce/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,12 @@ export default defineConfig({
},
build: {
sourcemap: true,
outDir: "build",
rollupOptions: {
output: {
plugins: [
// Replace the variables in our HTML files.
injectVariablesInHTML({
files: "build/index.html",
files: "dist/index.html",
variables: [
"%APP_VERSION%",
"%GIT_SHA%",
Expand Down Expand Up @@ -122,7 +121,7 @@ export default defineConfig({
checker({ typescript: true }),
// Bundle analyzer
visualizer({
filename: "build/source_map.html",
filename: "dist/source_map.html",
template: "treemap",
}),
sentryVitePlugin({
Expand All @@ -133,7 +132,7 @@ export default defineConfig({
name: process.env.npm_package_version,
},
sourcemaps: {
assets: "./build/assets/*",
assets: "dist/assets/*",
},
}),
],
Expand Down
4 changes: 4 additions & 0 deletions packages/deploy-utils/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
extends: ["@evg-ui"],
root: true,
};
3 changes: 3 additions & 0 deletions packages/deploy-utils/lint-staged.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import baseConfig from "@evg-ui/lint-staged";

export default baseConfig;
24 changes: 24 additions & 0 deletions packages/deploy-utils/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "@evg-ui/deploy-utils",
"version": "0.0.0",
"private": true,
"main": "src/index.ts",
"scripts": {
"check-types": "tsc -p tsconfig.json --noEmit",
"eslint:fix": "yarn eslint:strict --fix",
"eslint:staged": "STRICT=1 eslint",
"eslint:strict": "STRICT=1 eslint .",
"test": "vitest --typecheck=false"
},
"dependencies": {
"@evg-ui/lib": "*"
},
"devDependencies": {
"@evg-ui/eslint-config": "*",
"@types/node": "^20.12.7",
"eslint": "8.56.0",
"eslint-plugin-prettier": "5.1.3",
"typescript": "5.1.3",
"vitest": "1.6.0"
}
}
41 changes: 41 additions & 0 deletions packages/deploy-utils/src/deploy-remote/deploy-remote.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { mockEnvironmentVariables } from "@evg-ui/lib/test_utils/utils";
import { execSync } from "child_process";
import { deployRemote } from ".";
import { pushToS3 } from "../utils/s3";

const { cleanup, mockEnv } = mockEnvironmentVariables();

vi.mock("child_process", () => ({
execSync: vi.fn(),
}));

vi.mock("../utils/s3", () => ({
pushToS3: vi.fn(),
}));

describe("remote deploys", () => {
afterEach(() => {
vi.restoreAllMocks();
cleanup();
});

it("fails when no bucket env var exists", () => {
expect(() => deployRemote()).toThrowError("No bucket specified");
expect(vi.mocked(pushToS3)).not.toHaveBeenCalled();
});

it("calls pushToS3 function when BUCKET is defined", () => {
mockEnv("BUCKET", "bucket-name");
deployRemote();
expect(vi.mocked(pushToS3)).toHaveBeenCalledOnce();
expect(vi.mocked(pushToS3)).toHaveBeenCalledWith("bucket-name");
});

it("fails when yarn build fails", () => {
vi.mocked(execSync).mockImplementation(() => {
throw Error("mock yarn build error");
});
expect(() => deployRemote()).toThrowError("mock yarn build error");
expect(vi.mocked(pushToS3)).not.toHaveBeenCalled();
});
});
12 changes: 12 additions & 0 deletions packages/deploy-utils/src/deploy-remote/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { execSync } from "child_process";
import { pushToS3 } from "../utils/s3";

export const deployRemote = () => {
execSync("yarn build", { stdio: "inherit" });

if (process.env.BUCKET) {
pushToS3(process.env.BUCKET);
} else {
throw Error("No bucket specified.");
}
};
3 changes: 3 additions & 0 deletions packages/deploy-utils/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { setupCredentials } from "./utils/setup-credentials";
export { pushToS3 } from "./utils/s3";
export { deployRemote } from "./deploy-remote";
14 changes: 14 additions & 0 deletions packages/deploy-utils/src/utils/s3.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { execSync } from "child_process";

export const pushToS3 = (bucket: string) => {
console.log("Attempting to deploy to S3");
try {
execSync(
`aws s3 sync dist/ s3://"${bucket}"/ --acl public-read --follow-symlinks --delete --exclude .env-cmdrc.json`,
{ stdio: "inherit" },
);
console.log("Successfully deployed to S3");
} catch (e) {
throw Error("Deployment to S3 failed", { cause: e });
}
};
Loading

0 comments on commit 837d61b

Please sign in to comment.