Repository navigation
204 lines (174 loc) · 8.32 KB
/
Copy pathui-preview.yml
File metadata and controls
204 lines (174 loc) · 8.32 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
name: UI Preview
# Builds the standalone web client for a PR (or develop) and publishes it to ghcr.io, where Rocket.Chat Desktop
# pulls it anonymously (`rocketchat://ui-preview?pr=<number>`). A PR's preview is removed with its label or on close.
on:
push:
branches: [develop]
paths:
- 'apps/meteor/client/**'
- 'apps/meteor/app/**'
- 'apps/meteor/ee/client/**'
- 'apps/meteor/public/**'
- 'apps/meteor/vite/**'
- 'packages/**'
- 'ee/packages/**'
- 'yarn.lock'
# No path filter: it would also gate `unlabeled`/`closed`, leaving a preview behind. The `preview` label gates builds.
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled, closed]
concurrency:
# Adding or removing any other label must not cancel a preview build in progress.
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}${{ (github.event.action == 'labeled' || github.event.action == 'unlabeled') && github.event.label.name != 'preview' && format('-{0}', github.run_id) || '' }}
cancel-in-progress: true
env:
TOOL_NODE_FLAGS: ${{ vars.TOOL_NODE_FLAGS }}
IMAGE: ghcr.io/rocketchat/rocket.chat-web
permissions: {}
jobs:
build:
name: Build UI preview
# Opt-in through the `preview` label. Publishing needs CR_PAT, which fork and Dependabot PRs do not receive.
if: >-
github.event_name == 'push' || (
contains(github.event.pull_request.labels.*.name, 'preview') &&
github.event.action != 'unlabeled' && github.event.action != 'closed' &&
(github.event.action != 'labeled' || github.event.label.name == 'preview') &&
github.event.pull_request.head.repo.full_name == github.repository &&
github.actor != 'dependabot[bot]'
)
runs-on: ubuntu-24.04-arm
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup NodeJS
uses: ./.github/actions/setup-node
with:
cache-modules: true
install: true
- uses: rharkor/caching-for-turbo@2238fae6eb9a9936f92356f54cb3660200d105e7 # v2.5.1
# Same package set `yarn dev:next` builds against a remote server.
- name: Build packages the client reads from dist
run: |
mapfile -t filters < <(node --input-type=module -e "
import { distOnlyWorkspacePackages, publicAssetWorkspacePackages } from './apps/meteor/vite/workspacePackages.mjs';
console.log([...distOnlyWorkspacePackages, ...publicAssetWorkspacePackages].map((name) => '--filter=' + name + '...').join('\n'));
")
yarn turbo run build "${filters[@]}"
- name: Build standalone client
run: yarn workspace @rocket.chat/meteor build:vite
- name: Package bundle
run: |
mkdir -p ui-preview
# The rest of dist/ is public/, which the Rocket.Chat server already serves.
tar --format=ustar -czf ui-preview/ui-preview.tar.gz -C apps/meteor/vite/dist index.html bundle
du -h ui-preview/ui-preview.tar.gz
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: ui-preview
path: ui-preview
retention-days: 3
# Kept apart from the build so the job holding CR_PAT never runs the PR's code.
publish:
name: Publish UI preview
needs: build
runs-on: ubuntu-24.04-arm
permissions:
packages: write
pull-requests: write
steps:
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: ui-preview
path: ui-preview
- uses: oras-project/setup-oras@1d808f7d7f6995cc68b7bf507bfe5c5446e1dc9d # v2.0.1
- name: Push to ghcr.io
env:
CR_USER: ${{ secrets.CR_USER }}
CR_PAT: ${{ secrets.CR_PAT }}
NUMBER: ${{ github.event.pull_request.number }}
HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
REPO: ${{ github.repository }}
run: |
# `pr-<n>-<sha>` keeps every build of a PR findable after `pr-<n>` moves on, so cleanup can remove them all.
if [ -n "$NUMBER" ]; then tags="pr-$NUMBER,pr-$NUMBER-$HEAD_SHA,$HEAD_SHA"; else tags=develop; fi
echo "$CR_PAT" | oras login ghcr.io -u "$CR_USER" --password-stdin
cd ui-preview
oras push "$IMAGE:$tags" \
--artifact-type application/vnd.rocketchat.ui-preview.v1 \
--annotation "org.opencontainers.image.source=https://github.com/$REPO" \
--annotation "org.opencontainers.image.revision=$HEAD_SHA" \
ui-preview.tar.gz:application/vnd.oci.image.layer.v1.tar+gzip
- name: Delete superseded develop builds
if: github.event_name == 'push'
env:
GH_TOKEN: ${{ github.token }}
PACKAGE: /orgs/${{ github.repository_owner }}/packages/container/rocket.chat-web/versions
run: |
# List every page before deleting, or deletions shift the pages still to be read.
ids=$(gh api --paginate "$PACKAGE" -q '.[] | select(.metadata.container.tags == []) | .id')
printf '%s' "$ids" | xargs -r -I{} gh api -X DELETE "$PACKAGE/{}"
- name: Comment on PR
if: github.event_name == 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
NUMBER: ${{ github.event.pull_request.number }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
marker='<!-- ui-preview -->'
body="$marker
### 🖥️ UI preview
Built from \`${HEAD_SHA:0:7}\` and published to \`$IMAGE:pr-$NUMBER\`.
In Rocket.Chat Desktop with **Developer Mode** on, open one of these links to load this PR's UI into the workspace in focus:
| | |
|---|---|
| Latest build of this PR | \`rocketchat://ui-preview?pr=$NUMBER\` |
| This exact build | \`rocketchat://ui-preview?pr=$NUMBER&sha=$HEAD_SHA\` |
To pick the workspace, add \`&host=https://your.server\`. Use **View > Restore server UI**, or restart the app, to go back.
Or run it in a browser against any server (default \`https://open.rocket.chat\`):
\`\`\`sh
npx @rocket.chat/ui-preview $NUMBER --server https://open.rocket.chat
\`\`\`"
comment_id=$(gh api "repos/$REPO/issues/$NUMBER/comments" --paginate -q ".[] | select(.body | startswith(\"$marker\")) | .id" | head -n1)
if [ -n "$comment_id" ]; then
gh api -X PATCH "repos/$REPO/issues/comments/$comment_id" -f body="$body"
else
gh api "repos/$REPO/issues/$NUMBER/comments" -f body="$body"
fi
remove:
name: Remove UI preview
if: >-
github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name == github.repository && (
(github.event.action == 'unlabeled' && github.event.label.name == 'preview') ||
(github.event.action == 'closed' && contains(github.event.pull_request.labels.*.name, 'preview'))
)
runs-on: ubuntu-24.04-arm
permissions:
packages: write
pull-requests: write
steps:
- name: Delete from ghcr.io
env:
GH_TOKEN: ${{ github.token }}
PACKAGE: /orgs/${{ github.repository_owner }}/packages/container/rocket.chat-web/versions
NUMBER: ${{ github.event.pull_request.number }}
run: |
ids=$(gh api --paginate "$PACKAGE" \
-q ".[] | select(any(.metadata.container.tags[]; . == \"pr-$NUMBER\" or startswith(\"pr-$NUMBER-\"))) | .id")
printf '%s' "$ids" | xargs -r -I{} gh api -X DELETE "$PACKAGE/{}"
- name: Update PR comment
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
NUMBER: ${{ github.event.pull_request.number }}
run: |
marker='<!-- ui-preview -->'
body="$marker
### 🖥️ UI preview
Removed from \`$IMAGE\`. Add the \`preview\` label again to publish a new one."
comment_id=$(gh api "repos/$REPO/issues/$NUMBER/comments" --paginate -q ".[] | select(.body | startswith(\"$marker\")) | .id" | head -n1)
if [ -n "$comment_id" ]; then
gh api -X PATCH "repos/$REPO/issues/comments/$comment_id" -f body="$body"
fi