-
Notifications
You must be signed in to change notification settings - Fork 6
227 lines (203 loc) · 8.57 KB
/
Copy pathe2e-test.yml
File metadata and controls
227 lines (203 loc) · 8.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
---
# Run the E2E tests on a local stack that is using the local file system for backend file storage
name: e2e-tests
concurrency:
group: e2e-tests-${{ github.ref }}
cancel-in-progress: true
on:
push:
branches:
- "**"
- "!main"
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
permissions:
packages: read
contents: read
jobs:
detect-changes:
runs-on: ubuntu-latest
env:
IS_CI_AUTOMATION: "yes"
outputs:
backend-changed: ${{ steps.check.outputs.backend-changed }}
iac-changed: ${{ steps.check.outputs.iac-changed }}
frontend-changed: ${{ steps.check.outputs.frontend-changed }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: check
with:
filters: |
backend-changed:
- 'packages/send/backend/**'
iac-changed:
- 'packages/send/pulumi/**'
- '.github/workflows/validate.yml'
frontend-changed:
- 'packages/send/frontend/**'
shared-changed:
- 'packages/shared/**'
build-e2e-images:
needs: detect-changes
if: needs.detect-changes.outputs.backend-changed == 'true' || needs.detect-changes.outputs.frontend-changed == 'true'
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
env:
# -fs suffix distinguishes tags from the bucket-test workflow which uses -b2
BACKEND_IMAGE: ghcr.io/${{ github.repository }}/e2e-backend:${{ github.sha }}-fs
FRONTEND_IMAGE: ghcr.io/${{ github.repository }}/e2e-frontend:${{ github.sha }}-fs
PROXY_IMAGE: ghcr.io/${{ github.repository }}/e2e-reverse-proxy:${{ github.sha }}-fs
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Prepare backend build context
run: |
rsync -a \
--exclude=node_modules \
--exclude=.docker-build \
--exclude=.pnpm-store \
packages/send/backend/ \
packages/send/backend/.docker-build/
cp pnpm-lock.yaml packages/send/backend/.docker-build/
echo "node_modules/" > packages/send/backend/.docker-build/.dockerignore
- name: Build backend image
uses: docker/build-push-action@v6
with:
context: ./packages/send/backend/.docker-build
file: ./packages/send/backend/.docker-build/Dockerfile
build-args: BUILD_ENV=production
push: true
tags: ${{ env.BACKEND_IMAGE }}
cache-from: type=gha,scope=e2e-backend-fs
cache-to: type=gha,mode=max,scope=e2e-backend-fs
- name: Build reverse-proxy image
uses: docker/build-push-action@v6
with:
context: ./packages/send/backend/tls-dev-proxy
push: true
tags: ${{ env.PROXY_IMAGE }}
cache-from: type=gha,scope=e2e-reverse-proxy-fs
cache-to: type=gha,mode=max,scope=e2e-reverse-proxy-fs
- name: Build frontend image
uses: docker/build-push-action@v6
with:
context: ./
file: ./dockerfiles/Dockerfile-frontend
build-args: BUILD_ENV=production
push: true
tags: ${{ env.FRONTEND_IMAGE }}
cache-from: type=gha,scope=e2e-frontend-fs
cache-to: type=gha,mode=max,scope=e2e-frontend-fs
end-to-end-tests:
needs: [detect-changes, build-e2e-images]
if: needs.detect-changes.outputs.backend-changed == 'true' || needs.detect-changes.outputs.frontend-changed == 'true'
runs-on: ubuntu-latest
container:
image: ghcr.io/${{ github.repository }}/cached-devcontainer:latest
options: --shm-size=2gb --security-opt seccomp=unconfined
env:
IS_CI_AUTOMATION: "yes"
BACKEND_IMAGE: ghcr.io/${{ github.repository }}/e2e-backend:${{ github.sha }}-fs
FRONTEND_IMAGE: ghcr.io/${{ github.repository }}/e2e-frontend:${{ github.sha }}-fs
PROXY_IMAGE: ghcr.io/${{ github.repository }}/e2e-reverse-proxy:${{ github.sha }}-fs
PLAYWRIGHT_BROWSERS_PATH: /github/home/.cache/ms-playwright
steps:
- uses: actions/checkout@v4
- name: Set up environments and install dependencies
id: setup-and-install-dependencies
run: |
pnpm install --filter @thunderbird/tbpro-add-on && lerna run bootstrap
pnpm i --filter "send-*"
cd packages/send
# Setup local environment (use public login)
echo Y | pnpm setup:local
- name: Add env vars for backend
run: |
cd packages/send/backend
{
echo "OIDC_CLIENT_ID=${{ secrets.OIDC_CLIENT_ID }}"
echo "OIDC_CLIENT_SECRET=${{ secrets.OIDC_CLIENT_SECRET }}"
echo "OIDC_TOKEN_INTROSPECTION_URL=${{ secrets.OIDC_TOKEN_INTROSPECTION_URL }}"
} >> .env
- name: Add env vars for frontend
run: |
cd packages/send/frontend
echo "VITE_OIDC_CLIENT_ID=${{ secrets.VITE_OIDC_CLIENT_ID }}" >> .env
echo "VITE_OIDC_ROOT_URL=${{ secrets.VITE_OIDC_ROOT_URL }}" >> .env
- name: Restore Playwright browsers cache
uses: actions/cache/restore@v4
id: playwright-cache
with:
path: ${{ env.PLAYWRIGHT_BROWSERS_PATH }}
key: playwright-${{ runner.os }}-${{ hashFiles('packages/send/e2e/package.json') }}
- name: Restore apt packages cache
uses: actions/cache/restore@v4
id: apt-cache
with:
path: /var/cache/apt/archives
key: apt-playwright-${{ runner.os }}-${{ hashFiles('packages/send/e2e/package.json') }}
restore-keys: |
apt-playwright-${{ runner.os }}-
- name: Install Playwright system dependencies
run: |
# docker-clean deletes .deb files from /var/cache/apt/archives after dpkg runs,
# which would leave our apt cache empty. Remove it so downloads persist for caching.
rm -f /etc/apt/apt.conf.d/docker-clean
pnpm --filter send-suite-e2e exec playwright install-deps
# Pin the Node version used to install/run Playwright (see packages/send/e2e/.tool-versions).
# The container's default Node (24.x) hits a stream regression (nodejs/node#63487) that
# hangs `playwright install` during zip extraction; Node 22 LTS avoids it. We keep
# @playwright/test at 1.59.1 for BrowserStack Automate compatibility.
- name: Install pinned Node via mise
working-directory: packages/send/e2e
run: |
mise install
mise exec -- node --version
- name: Install Playwright browsers
id: install-playwright-browsers
if: steps.playwright-cache.outputs.cache-hit != 'true'
timeout-minutes: 10
working-directory: packages/send/e2e
run: mise exec -- pnpm exec playwright install
- name: Run stack and test
id: run-stack-and-test
timeout-minutes: 10
run: |
# Create .env file with secrets (for end to end run only)
echo "TBPRO_USERNAME=${{ secrets.TBPRO_USERNAME }}" > .env
echo "TBPRO_PASSWORD=${{ secrets.TBPRO_PASSWORD }}" >> .env
# The dev OIDC spec loads credentials from tests/desktop/dev/.env
# (send.spec.ts: dotenv path = __dirname/.env), so place it there too.
cp .env packages/send/e2e
mv .env packages/send/e2e/tests/desktop/dev/
cd packages/send/e2e
mise exec -- pnpm run test:e2e:ci
# Only save when the install step actually succeeded. A cancelled or failed
# install (e.g. the Node 24 extract-zip hang) would otherwise save a partial
# cache that poisons future runs with "Executable doesn't exist".
- name: Save Playwright browsers cache
if: always() && steps.playwright-cache.outputs.cache-hit != 'true' && steps.install-playwright-browsers.outcome == 'success'
uses: actions/cache/save@v4
with:
path: ${{ env.PLAYWRIGHT_BROWSERS_PATH }}
key: playwright-${{ runner.os }}-${{ hashFiles('packages/send/e2e/package.json') }}
- name: Save apt packages cache
if: always()
uses: actions/cache/save@v4
with:
path: /var/cache/apt/archives
key: ${{ steps.apt-cache.outputs.cache-primary-key }}
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: packages/send/e2e/playwright-report/
retention-days: 30