-
Notifications
You must be signed in to change notification settings - Fork 7
336 lines (301 loc) · 14.4 KB
/
extensions.yml
File metadata and controls
336 lines (301 loc) · 14.4 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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
name: Extension Workflow
on:
pull_request:
push:
branches:
- main
jobs:
# Detects file changes in extension directories that utilize the `simple-extensions`
# job below
simple-extension-changes:
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
# Expose matched filters as 'changes' output variable
changes: ${{ steps.changes.outputs.changes }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: changes
with:
# Adding a new extension that has a directory that can be TARed?
# Add a new line here with the name of the extension as the name of
# the filter and the value as the extension's directory path
# Be sure the extension name and directory name are the same
# e.g. `extension-name: extensions/extension-name/**`
filters: |
reaper: extensions/reaper/**
integration-session-manager: extensions/integration-session-manager/**
quarto-stock-report-python: extensions/quarto-stock-report-python/**
quarto-website: extensions/quarto-website/**
portfolio-dashboard: extensions/portfolio-dashboard/**
top-5-income-share-shiny: extensions/top-5-income-share-shiny/**
quarto-document: extensions/quarto-document/**
stock-api-plumber: extensions/stock-api-plumber/**
stock-api-flask: extensions/stock-api-flask/**
stock-dashboard-python: extensions/stock-dashboard-python/**
top-5-income-share-bokeh: extensions/top-5-income-share-bokeh/**
landing-page: extensions/landing-page/**
quarto-stock-report-r: extensions/quarto-stock-report-r/**
stock-api-fastapi: extensions/stock-api-fastapi/**
quarto-presentation: extensions/quarto-presentation/**
script-python: extensions/script-python/**
connectwidgets-example: extensions/connectwidgets-example/**
plumbertableau-example: extensions/plumbertableau-example/**
fastapitableau-example: extensions/fastapitableau-example/**
portfolio-report: extensions/portfolio-report/**
script-r: extensions/script-r/**
top-5-income-share-streamlit: extensions/top-5-income-share-streamlit/**
stock-report-jupyter: extensions/stock-report-jupyter/**
content-health-monitor: extensions/content-health-monitor/**
voila-example: extensions/voila-example/**
stock-report: extensions/stock-report/**
simple-mcp-server: extensions/simple-mcp-server/**
simple-shiny-chat-with-mcp: extensions/simple-shiny-chat-with-mcp/**
chat-with-content: extensions/chat-with-content/**
pqr: extensions/pqr/**
claude-chat: extensions/claude-chat/**
# Runs for each extension that has changed from `simple-extension-changes`
# Lints and packages in preparation for tests and and release.
simple-extensions:
needs: [simple-extension-changes]
# Will only run if there are changes in the simple extensions
# https://github.com/dorny/paths-filter/issues/66#issuecomment-778267385
if: ${{ needs.simple-extension-changes.outputs.changes != '[]' && needs.simple-extension-changes.outputs.changes != '' }}
strategy:
# Do not fail fast so all extensions are processed
fail-fast: false
matrix:
# Parse JSON containing names of all filters matching any of changed extensions
# e.g. ['reaper'] if the reaper extension dir changed
extension: ${{ fromJSON(needs.simple-extension-changes.outputs.changes) }}
runs-on: ubuntu-latest
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/lint-extension
with:
extension-name: ${{ matrix.extension }}
- uses: ./.github/actions/package-extension
with:
extension-name: ${{ matrix.extension }}
# Uploading an artifact to reflect extensions that were successfully linted and packaged.
# Using artifacts to avoid explicit output names for each simple extensions, requiring
# less file changes when adding simple extensions to this workflow.
# https://github.com/orgs/community/discussions/17245
- name: Mark successful jobs
run: echo "${{ matrix.extension }}" >> ${{ matrix.extension }}.packaged.successfully
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.extension }}.packaged.successfully
path: ${{ matrix.extension }}.packaged.successfully
retention-days: 1
# Collect success results from the matrix simple-extensions jobs for later use
collect-simple-extensions:
needs: simple-extensions
runs-on: ubuntu-latest
outputs:
successful_extensions: ${{ steps.collect.outputs.successful_extensions }}
steps:
- uses: actions/download-artifact@v4
with:
# Uses artifacts generated from package-extension which are only present if packaging was successful
pattern: "*.packaged.successfully"
path: packages
merge-multiple: true
- id: collect
run: |
SUCCESS_LIST=()
if [ -d "packages" ]; then
for FILE in packages/*.packaged.successfully; do
if [ -f "$FILE" ]; then
# Extract extension name from filename (remove .packaged.successfully)
EXT=$(basename "$FILE" .packaged.successfully)
SUCCESS_LIST+=("$EXT")
echo "Found successful extension package: $EXT"
fi
done
fi
SUCCESSFUL_EXTENSIONS=$(jq -n --arg arr "$(IFS=,; echo "${SUCCESS_LIST[*]}")" \
'$arr | split(",")' -c)
echo "Successful extensions: $SUCCESSFUL_EXTENSIONS"
echo "successful_extensions=$SUCCESSFUL_EXTENSIONS" >> "$GITHUB_OUTPUT"
# Runs Connect integration tests for each extension that were successfully linted and packaged
simple-extension-connect-integration-tests:
needs: [collect-simple-extensions]
uses: ./.github/workflows/connect-integration-tests.yml
with:
extensions: ${{ needs.collect-simple-extensions.outputs.successful_extensions }}
if: fromJSON(needs.collect-simple-extensions.outputs.successful_extensions) != '[]'
secrets: inherit
# Runs the release process for each extension that was packaged, passed all tests, if the semver is updated, on main
simple-extension-release:
runs-on: ubuntu-latest
needs: [simple-extension-connect-integration-tests]
# Only run if connect integration tests actually ran and produced valid output
if: ${{
always() &&
needs.simple-extension-connect-integration-tests.result != 'skipped' &&
needs.simple-extension-connect-integration-tests.result != 'canceled' &&
needs.simple-extension-connect-integration-tests.outputs.successful_extensions != '[]'
}}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
strategy:
# Do not fail fast so all extensions are processed
fail-fast: false
matrix:
# Ensure the matrix is set to only process extensions that passed ALL integration tests
extension: ${{ fromJSON(needs.simple-extension-connect-integration-tests.outputs.successful_extensions) }}
# Extensions are only released when this workflow triggers on `main`
# otherwise, the release is skipped
# See the action comments for more details
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/release-extension
with:
extension-name: ${{ matrix.extension }}
# Detects file changes for complex extension directories that require more
# than the `simple-extensions` job offers.
# For example, run a build script prior to packaging the extension TAR
complex-extension-changes:
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
# Adding a new extension with a complex build process?
# Add a new line here with the name of the extension as the name of the
# filter and the step output variable below
# e.g. `extension-name: ${{ steps.changes.outputs.extension-name }}`
# Be sure the extension name and directory name it is in are the same
publisher-command-center: ${{ steps.changes.outputs.publisher-command-center }}
package-vulnerability-scanner: ${{ steps.changes.outputs.package-vulnerability-scanner }}
runtime-version-scanner: ${{ steps.changes.outputs.runtime-version-scanner }}
usage-metrics-dashboard: ${{ steps.changes.outputs.usage-metrics-dashboard }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: changes
with:
# Adding a new extension that has a complex build process?
# Add a new line here with the name of the extension and directory path
# Be sure the extension name and directory have the same name
# e.g. `extension-name: extensions/extension-name/**`
filters: |
publisher-command-center: extensions/publisher-command-center/**
package-vulnerability-scanner: extensions/package-vulnerability-scanner/**
runtime-version-scanner: extensions/runtime-version-scanner/**
usage-metrics-dashboard: extensions/usage-metrics-dashboard/**
# Creates and releases the Publisher Command Center extension using a custom
# workflow
publisher-command-center:
needs: [complex-extension-changes]
# Only runs if the `complex-extension-changes` job detects changes in the
# publisher-command-center extension directory
if: ${{ needs.complex-extension-changes.outputs.publisher-command-center == 'true' }}
uses: ./.github/workflows/publisher-command-center.yml
secrets: inherit
# Creates and releases the Package Vulnerability Scanner extension using a custom workflow
package-vulnerability-scanner:
needs: [complex-extension-changes]
# Only runs if the `complex-extension-changes` job detects changes in the
# package-vulnerability-scanner extension directory
if: ${{ needs.complex-extension-changes.outputs.package-vulnerability-scanner == 'true' }}
uses: ./.github/workflows/package-vulnerability-scanner.yml
secrets: inherit
# Creates and releases the Runtime Version Scanner extension using a custom workflow
runtime-version-scanner:
needs: [complex-extension-changes]
# Only runs if the `complex-extension-changes` job detects changes in the
# runtime-version-scanner extension directory
if: ${{ needs.complex-extension-changes.outputs.runtime-version-scanner == 'true' }}
uses: ./.github/workflows/runtime-version-scanner.yml
secrets: inherit
# Creates and releases the Usage Metrics Dashboard extension using a custom workflow
usage-metrics-dashboard:
needs: [complex-extension-changes]
# Only runs if the `complex-extension-changes` job detects changes in the
# usage-metrics-dashboard extension directory
if: ${{ needs.complex-extension-changes.outputs.usage-metrics-dashboard == 'true' }}
uses: ./.github/workflows/usage-metrics-dashboard.yml
secrets: inherit
# All extensions have been linted, packaged, and released, if necessary
# Continuing to update the extension list with the latest release data
# Gathers all release data from GitHub releases triggered by this workflow
# For use in the `update-extension-list` job
# If no releases were triggered the output for releases will be `[]`
fetch-releases:
runs-on: ubuntu-latest
# Requires that the `simple-extensions` and all custom workflow jobs are
# completed before running this job
needs: [
simple-extension-release,
publisher-command-center,
package-vulnerability-scanner,
runtime-version-scanner,
usage-metrics-dashboard,
]
if: ${{ always() }}
outputs:
releases: ${{ steps.fetch-releases.outputs.releases }}
steps:
# Downloads every release data file from the release-extension action
# merging them under the .releases/ directory
- name: Download GitHub release data
uses: actions/download-artifact@v4
with:
pattern: release-*.json
path: releases
merge-multiple: true
# We use jq --slurp to create a single JSON array from all the JSON files
# to use in the `update-extension-list` job
- name: Fetch releases
id: fetch-releases
run: echo "releases=$(cat releases/*.json | jq -c --slurp .)" >> "$GITHUB_OUTPUT"
# Updates the `extensions.json` file with the latest release data from
# all extensions that were released in this workflow using the `fetch-releases`
# job output
update-extension-list:
runs-on: ubuntu-latest
needs: [fetch-releases]
# Only runs if there are releases to update the extension list with
# https://github.com/actions/runner/issues/2205
if: ${{ always() && needs.fetch-releases.result == 'success' && needs.fetch-releases.outputs.releases != '[]' }}
# Sets the RELEASES environment variable for the extension list update
# script to read in
env:
RELEASES: ${{ needs.fetch-releases.outputs.releases }}
steps:
- name: Generate token for GitHub App
id: generate-token
uses: actions/create-github-app-token@v2
with:
app-id: 1129585
private-key: ${{ secrets.POSIT_CONNECT_PROJECTS_PEM }}
permission-contents: write
# Checkout main to commit the updated extension list
# reduces the chance of conflicts when updating the extension list with
# multiple running workflows
- uses: actions/checkout@v6
with:
ref: main
token: ${{ steps.generate-token.outputs.token }}
- uses: actions/setup-node@v4
with:
node-version: "lts/*"
cache: "npm"
cache-dependency-path: scripts/package-lock.json
- run: npm ci
working-directory: ./scripts
- run: npm run update-extension-list
working-directory: ./scripts
# Commits and pushes the updated extension list to the repository
# https://github.com/actions/checkout/tree/v4/?tab=readme-ov-file#push-a-commit-using-the-built-in-token
- run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add extensions.json
git commit -m "Update extension list"
git push