Chat with Content Extension V1 #604
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/** | |
usage-metrics-dashboard: extensions/usage-metrics-dashboard/** | |
app-canary: extensions/app-canary/** | |
voila-example: extensions/voila-example/** | |
stock-report: extensions/stock-report/** | |
# 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 }} | |
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/** | |
# 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 | |
# 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] | |
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: | |
# 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@v4 | |
with: | |
ref: main | |
ssh-key: ${{ secrets.DEPLOY_KEY }} | |
- 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 |