Skip to content

Commit 4589320

Browse files
ci: full transition to GitHub Actions (#666)
1 parent 8b91912 commit 4589320

File tree

17 files changed

+532
-203
lines changed

17 files changed

+532
-203
lines changed

.github/README.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# GitHub Actions
2+
3+
GitHub Actions runs using workflows, which define jobs that we run for continuous integration (CI). Inside of our GitHub Actions, we have 4 different kinds of workflows:
4+
5+
- [Core - Linting, Unit Tests, and Non-Snapshot Functional Tests](#linting-unit-tests-and-non-snapshot-functional-tests-core-yml)
6+
- [Snapshot Comparison](#snapshot-comparison-snapshot-compare-yml)
7+
- [Update Snapshots](#update-snapshots-snapshot-update-yml)
8+
- [Commit Snapshots](#commit-snapshots-snapshot-commit-yml)
9+
- [Release](#release-release-yml)
10+
11+
Snapshot-based workflows are split further by US and non-US due to the numerous offers that US has. This keeps our CI running quickly.
12+
13+
14+
## Core - Linting, Unit Tests, and Non-Snapshot Functional Tests (core.yml)
15+
16+
This workflow runs two jobs.
17+
18+
`lintAndUnit`
19+
20+
1. Lints code to make sure it follows coding standards.
21+
2. Runs unit tests to ensure code is working at a basic level.
22+
23+
`functionalNonSnapshot`
24+
25+
1. Runs non-snapshot functional tests to ensure that code works when it runs in the browser.
26+
27+
28+
## Snapshot Comparison (snapshotCompare.yml)
29+
30+
This workflow runs two jobs.
31+
32+
`compareSnapshots`
33+
34+
1. Reads `matrix.json` and provides it as output.
35+
2. Takes each locale and group to output a JSON array of valid testPathPatterns.
36+
37+
`compareSnapshots`
38+
39+
1. `compareSnapshots` reads the output of `getMatrix` to determine the tests to run.
40+
2. The server is run.
41+
3. Any failed comparison tests are collected and uploaded to imgur.
42+
43+
44+
## Update Snapshots (snapshotUpdate.yml)
45+
46+
This workflow runs three jobs.
47+
48+
`getMatrix`
49+
50+
1. Reads `matrix.json` and provides it as output.
51+
2. Takes each locale and group to output a JSON array of valid testPathPatterns.
52+
53+
`captureMetadata`
54+
55+
1. Saves the pull request number to a file.
56+
57+
`updateSnapshots`
58+
59+
1. Reads the output of `getMatrix` to determine which tests may need updating.
60+
2. The server is run.
61+
3. Any comparison tests that failed in Snapshot Comparison will have their images updated.
62+
4. Saves updated images as artifacts (workflow storage).
63+
64+
## Commit Snapshots (snapshotCommit.yml)
65+
66+
This workflow runs one job.
67+
68+
`commit`
69+
70+
1. Downloads the snapshot image artifacts from `updateSnapshots`.
71+
2. Removes the `snapshots` label.
72+
3. Commits thee snapshot images.
73+
74+
75+
## Release (release.yml)
76+
77+
This workflow runs three jobs.
78+
79+
`core`
80+
81+
1. See [Core - Linting, Unit Tests, and Non-Snapshot Functional Tests](#linting-unit-tests-and-non-snapshot-functional-tests-core-yml)
82+
83+
`compareSnapshots`
84+
85+
1. See [Snapshot Comparison](#snapshot-comparison-snapshot-compare-yml)
86+
87+
`release`
88+
89+
1. Runs semantic-release to create a new release
90+
91+
92+
## Workflow Triggers
93+
94+
Triggers are what causes a workflow to run. These are the current triggers for each of our workflows.
95+
96+
- Linting, Unit Tests, and Non-Snapshot Functional Tests
97+
- `workflow_dispatch` - allows for manually running a workflow
98+
- `push` - runs the workflow when code is pushed to `develop` or `release`
99+
- `pull_request` - runs on all pull requests
100+
- Snapshot Comparison
101+
- `workflow_dispatch` - allows for manually running a workflow
102+
- `workflow_call` -
103+
- `push` - runs the workflow when code is pushed to `develop` or `release`
104+
- `pull_request` - runs on all pull requests
105+
- **Note** - `push` and `pull_request` run US or non-US workflows if their related files are changed
106+
- Update Snapshots
107+
- `workflow_dispatch` - allows for manually running a workflow
108+
- `pull_request` - runs on all pull requests
109+
- `pull_request_target` - runs on all pull requests from forks if the pull request has a label on it
110+
- **Note** - this workflow only runs if it is labeled with `snapshots`
111+
- Commit Snapshots
112+
- `workflow_run` - runs wheen another workflow finishes
113+
- Release
114+
- `workflow_dispatch` - allows for manually running a workflow
115+
- `push` - runs the workflow when code is pushed to `release`
116+
117+
118+
## Other Notes
119+
120+
### Strategy Matrix
121+
122+
The strategy matrix makes it easy to run the same job with a different configuration.
123+
124+
This matrix is used to run snapshot tests for each locale and to split the US locale by various test path patterns. The `matrix` option is generated dynamically by reading in `matrix.json`. This is done so developers can change `locale` and `groups` in one place and every workflow using those options stays in sync.
125+
126+
You can read more in the [official docs here](https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix).

.github/configs/matrix.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"locales": ["US", "DE", "AU", "FR", "GB"],
3+
"groups": ["banner/text", "banner/flex", "modal/calc", "modal/base", "modal/standalone", "custom/custom"]
4+
}

.github/scripts/runServer.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/bash
2+
3+
echo "127.0.0.1 localhost.paypal.com" | sudo tee -a /etc/hosts
4+
5+
((npm run dev:standalone 2>&1 & echo $! > pid.log) | tee server.log) &
6+
sleep 40
7+
8+
error_count=$(grep -i error server.log | wc -l)
9+
echo "Errors Found: $error_count"
10+
if [[ $error_count -gt 0 ]]; then
11+
echo "Exiting server"
12+
kill $(<pid.log)
13+
exit 1
14+
fi

.github/workflows/core.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Use "act" for local testing: https://github.com/nektos/act
2+
name: Lint, Unit, Non-snapshot tests
3+
on:
4+
# allow for manual triggers
5+
workflow_dispatch: {}
6+
workflow_call: {}
7+
push:
8+
branches:
9+
- develop
10+
pull_request: {}
11+
12+
jobs:
13+
lintAndUnit:
14+
name: Lint and Unit Tests
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout repo
18+
uses: actions/checkout@v2
19+
20+
- name: Setup node
21+
uses: actions/setup-node@v1
22+
with:
23+
node-version: 12
24+
25+
- name: 📥 Download deps
26+
uses: bahmutov/npm-install@v1
27+
with:
28+
useLockFile: false
29+
30+
- name: Lint
31+
run: npm run lint
32+
33+
- name: Unit Tests
34+
run: npm run test
35+
36+
functionalNonSnapshot:
37+
name: Functional Non-Snapshot Tests
38+
runs-on: ubuntu-latest
39+
steps:
40+
- name: Checkout repo
41+
uses: actions/checkout@v2
42+
43+
- name: Setup node
44+
uses: actions/setup-node@v1
45+
with:
46+
node-version: 12
47+
48+
- name: 📥 Download deps
49+
uses: bahmutov/npm-install@v1
50+
with:
51+
useLockFile: false
52+
53+
- name: Run server
54+
run: ./.github/scripts/runServer.sh
55+
56+
- name: Functional Non-Snapshot Tests
57+
run: npm run test:func:nosnaps

.github/workflows/main.yml

Lines changed: 0 additions & 55 deletions
This file was deleted.

.github/workflows/release.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Release
2+
on:
3+
# allow for manual triggers
4+
workflow_dispatch: {}
5+
push:
6+
branches:
7+
- release
8+
9+
jobs:
10+
core:
11+
uses: paypal/paypal-messaging-components/.github/workflows/core.yml@release
12+
13+
compareSnapshots:
14+
uses: paypal/paypal-messaging-components/.github/workflows/snapshotCompare.yml@release
15+
16+
release:
17+
name: Release
18+
needs: [core, compareSnapshots]
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout repo
22+
uses: actions/checkout@v2
23+
with:
24+
# pulls all commits (needed for semantic release to correctly version)
25+
fetch-depth: '0'
26+
27+
- name: Setup node
28+
uses: actions/setup-node@v1
29+
with:
30+
node-version: 14
31+
32+
- name: 📥 Download deps
33+
uses: bahmutov/npm-install@v1
34+
with:
35+
useLockFile: false
36+
37+
- name: Release
38+
env:
39+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40+
run: npx semantic-release@18

.github/workflows/snapshotCommit.yml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: Commit Snapshots
2+
3+
on:
4+
workflow_run:
5+
workflows: ['Update Snapshots']
6+
types:
7+
- completed
8+
9+
jobs:
10+
commit:
11+
name: Commit Snapshots
12+
if: github.event.workflow_run.conclusion == 'success'
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout repo
16+
uses: actions/checkout@v2
17+
with:
18+
ref: ${{ github.event.workflow_run.head_branch }}
19+
repository: ${{ github.event.workflow_run.head_repository.full_name }}
20+
token: ${{ secrets.COMMIT_TOKEN }}
21+
22+
- name: Download Artifacts
23+
uses: actions/[email protected]
24+
with:
25+
script: |
26+
const fs = require('fs');
27+
const { execSync } = require('child_process');
28+
29+
const artifacts = await github.actions.listWorkflowRunArtifacts({
30+
owner: context.repo.owner,
31+
repo: context.repo.repo,
32+
run_id: context.payload.workflow_run.id
33+
});
34+
35+
await Promise.all(
36+
artifacts.data.artifacts.map(async (artifact) => {
37+
const download = await github.actions.downloadArtifact({
38+
owner: context.repo.owner,
39+
repo: context.repo.repo,
40+
artifact_id: artifact.id,
41+
archive_format: 'zip'
42+
});
43+
44+
fs.writeFileSync(`${{ github.workspace }}/${artifact.name}.zip`, Buffer.from(download.data));
45+
46+
if (artifact.name === 'metadata') {
47+
execSync(`unzip -o ${{ github.workspace }}/${artifact.name}.zip`);
48+
} else {
49+
execSync(`unzip -o ${{ github.workspace }}/${artifact.name}.zip -d tests/functional/snapshots`);
50+
}
51+
})
52+
);
53+
54+
- name: Reset Label
55+
if: github.event.workflow_run.event == 'pull_request'
56+
uses: actions/[email protected]
57+
with:
58+
# The workflow_run that comes along with the event drops the PR number for some reason
59+
# so we have to pass the PR number from the original workflow as an artifact
60+
script: |
61+
const fs = require('fs');
62+
63+
const pullNumber = fs.readFileSync('./pull_number.txt', 'utf8');
64+
65+
await github.issues.removeLabel({
66+
owner: context.repo.owner,
67+
repo: context.repo.repo,
68+
issue_number: pullNumber,
69+
name: 'snapshots'
70+
}).catch(() => {
71+
console.log('snapshots label has already been removed');
72+
});
73+
74+
- name: Commit Updated Snapshots
75+
uses: stefanzweifel/git-auto-commit-action@v4
76+
with:
77+
commit_message: 'chore(snapshots): ${{ github.event.workflow.name }} [skip ci]'
78+
commit_options: '--no-verify --quiet'
79+
file_pattern: tests/functional/snapshots
80+
push_options: '-v'

0 commit comments

Comments
 (0)