Repository navigation
Align operating skill and bundled CLI with playlist preparation workflows #118
Workflow file for this run
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: public plugin gates | |
| on: | |
| pull_request: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: public-plugin-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| verify: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: "22" | |
| - name: Pack current screenrig/cli main | |
| run: | | |
| repository="screenrig/cli" | |
| filename="screenrig-cli.tgz" | |
| test "$(jq -r .state components.lock.json)" = resolved | |
| test "$(jq -r .cli.repository components.lock.json)" = "${repository}" | |
| # Pack current main. Do not refetch a SHA from components.lock.json; | |
| # that file is provenance of the tarball just packed. | |
| install -d "${RUNNER_TEMP}/screenrig-cli-source" | |
| git -C "${RUNNER_TEMP}/screenrig-cli-source" init --quiet | |
| git -C "${RUNNER_TEMP}/screenrig-cli-source" fetch --depth=1 \ | |
| "https://github.com/${repository}.git" main | |
| git -C "${RUNNER_TEMP}/screenrig-cli-source" checkout --quiet --detach FETCH_HEAD | |
| commit="$(git -C "${RUNNER_TEMP}/screenrig-cli-source" rev-parse HEAD)" | |
| # Stamp the same CalVer the CLI distributing job used when this | |
| # main HEAD is tagged vYY.MM.N, so the tarball hash is stable. | |
| cli_version="$(python3 scripts/calver.py cli-stamp --repository "${repository}" --commit "${commit}")" | |
| if [ -n "${cli_version}" ]; then | |
| export SCREENRIG_VERSION="${cli_version}" | |
| git -C "${RUNNER_TEMP}/screenrig-cli-source" fetch --depth=1 \ | |
| "https://github.com/${repository}.git" \ | |
| "refs/tags/v${cli_version}:refs/tags/v${cli_version}" || true | |
| fi | |
| npm --prefix "${RUNNER_TEMP}/screenrig-cli-source" ci | |
| npm --prefix "${RUNNER_TEMP}/screenrig-cli-source" run build | |
| install -d "${RUNNER_TEMP}/screenrig-cli" | |
| bash "${RUNNER_TEMP}/screenrig-cli-source/scripts/package-release.sh" \ | |
| "${RUNNER_TEMP}/screenrig-cli/${filename}" | |
| test -f "${RUNNER_TEMP}/screenrig-cli/${filename}" | |
| printf '%s' "${commit}" > "${RUNNER_TEMP}/screenrig-cli/commit" | |
| - name: Rebuild and verify the committed plugin bundle | |
| run: | | |
| filename="screenrig-cli.tgz" | |
| artifact="${RUNNER_TEMP}/screenrig-cli/${filename}" | |
| commit="$(cat "${RUNNER_TEMP}/screenrig-cli/commit")" | |
| packed="$(sha256sum "${artifact}" | awk '{print $1}')" | |
| locked="$(jq -r .cli.artifact.sha256 components.lock.json)" | |
| if [ "${packed}" != "${locked}" ]; then | |
| if [ "${GITHUB_REF}" != "refs/heads/main" ]; then | |
| echo "Committed CLI tarball provenance differs from current screenrig/cli main" >&2 | |
| echo "packed ${packed}" >&2 | |
| echo "recorded ${locked}" >&2 | |
| exit 1 | |
| fi | |
| python3 scripts/build-plugin.py --cli-artifact "${artifact}" --write-lock --cli-commit "${commit}" | |
| install -d "${RUNNER_TEMP}/screenrig-cli-bundle-update" | |
| cp components.lock.json "${RUNNER_TEMP}/screenrig-cli-bundle-update/components.lock.json" | |
| cp -a plugins/screenrig "${RUNNER_TEMP}/screenrig-cli-bundle-update/plugins-screenrig" | |
| fi | |
| python3 scripts/build-plugin.py --check --cli-artifact "${artifact}" | |
| python3 scripts/validate-plugin.py --cli-artifact "${artifact}" --cli-source "${RUNNER_TEMP}/screenrig-cli-source" | |
| python3 scripts/check-public-repo.py | |
| PYTHONDONTWRITEBYTECODE=1 python3 scripts/test-public-dependencies.py | |
| python3 scripts/test-skill-commands.py | |
| PYTHONDONTWRITEBYTECODE=1 python3 scripts/test-launcher.py | |
| PYTHONDONTWRITEBYTECODE=1 python3 scripts/test-plugin-freshness.py | |
| - name: Enforce plugin bundle size budget | |
| run: | | |
| set -euo pipefail | |
| tree_bytes="$(du -sb plugins/screenrig | cut -f1)" | |
| test "${tree_bytes}" -le 356515840 || { | |
| echo "plugins/screenrig is ${tree_bytes} bytes, over the 340 MiB budget" >&2 | |
| exit 1 | |
| } | |
| tar_bytes="$(tar --sort=name --format=ustar --mtime=@0 --owner=0 --group=0 \ | |
| --numeric-owner --mode=u=rwX,go=rX -C plugins/screenrig -cf - . \ | |
| | gzip -n -9 | wc -c)" | |
| test "${tar_bytes}" -le 152043520 || { | |
| echo "plugin archive is ${tar_bytes} bytes, over the 145 MiB budget" >&2 | |
| exit 1 | |
| } | |
| stray="$(find plugins/screenrig -type f -size +2M ! -path '*/@napi-rs/*')" | |
| test -z "${stray}" || { | |
| echo "unexpectedly large bundle files:" >&2 | |
| printf '%s\n' "${stray}" >&2 | |
| exit 1 | |
| } | |
| - name: Upload rebuilt marketplace CLI when it drifted | |
| if: github.ref == 'refs/heads/main' | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: screenrig-cli-bundle-update | |
| path: ${{ runner.temp }}/screenrig-cli-bundle-update/ | |
| # v4 omits dotfiles unless set; that deleted .claude-plugin/plugin.json. | |
| include-hidden-files: true | |
| if-no-files-found: ignore | |
| retention-days: 1 | |
| - name: Package deterministic plugin artifact | |
| if: github.ref != 'refs/heads/main' | |
| run: >- | |
| tar --sort=name --format=ustar --mtime=@0 --owner=0 --group=0 | |
| --numeric-owner --mode=u=rwX,go=rX -C plugins/screenrig -cf - . | |
| | gzip -n -9 > "${RUNNER_TEMP}/screenrig-plugin.tar.gz" | |
| - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| if: github.ref != 'refs/heads/main' | |
| with: | |
| name: screenrig-plugin | |
| path: ${{ runner.temp }}/screenrig-plugin.tar.gz | |
| if-no-files-found: error | |
| retention-days: 14 | |
| distribute: | |
| if: github.repository == 'screenrig/plugin' && github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') | |
| needs: verify | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 | |
| continue-on-error: true | |
| with: | |
| name: screenrig-cli-bundle-update | |
| path: ${{ runner.temp }}/screenrig-cli-bundle-update | |
| - name: Publish current CLI bundle when screenrig/cli main moved | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| update="${RUNNER_TEMP}/screenrig-cli-bundle-update/components.lock.json" | |
| if [ ! -f "${update}" ]; then | |
| echo "Committed marketplace CLI already matches screenrig/cli main" | |
| exit 0 | |
| fi | |
| old="$(jq -r .cli.artifact.sha256 components.lock.json)" | |
| new="$(jq -r .cli.artifact.sha256 "${update}")" | |
| if [ "${old}" = "${new}" ]; then | |
| echo "Bundled CLI digest unchanged; not committing" | |
| exit 0 | |
| fi | |
| cp "${update}" components.lock.json | |
| rm -rf plugins/screenrig | |
| cp -a "${RUNNER_TEMP}/screenrig-cli-bundle-update/plugins-screenrig" plugins/screenrig | |
| # download-artifact restores files as 644. | |
| chmod 0755 plugins/screenrig/cli/dist/bin.js \ | |
| plugins/screenrig/skills/screenrig/scripts/screenrig \ | |
| plugins/screenrig/skills/screenrig/scripts/screenrig-plugin-freshness | |
| git add -- components.lock.json plugins/screenrig | |
| git diff --cached --quiet && exit 0 | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git commit -m "Bundle current screenrig/cli main" | |
| git push origin "HEAD:${GITHUB_REF_NAME}" | |
| - name: Tag this commit and stamp the distributing artifact | |
| run: | | |
| version="$(python3 scripts/calver.py tag)" | |
| staging="${RUNNER_TEMP}/screenrig-plugin-stamp" | |
| install -d "${staging}" | |
| cp -a plugins/screenrig "${staging}/screenrig" | |
| cp .claude-plugin/marketplace.json "${staging}/marketplace.json" | |
| python3 scripts/calver.py stamp --version "${version}" \ | |
| --marketplace "${staging}/marketplace.json" \ | |
| --plugin-root "${staging}/screenrig" | |
| tar --sort=name --format=ustar --mtime=@0 --owner=0 --group=0 \ | |
| --numeric-owner --mode=u=rwX,go=rX -C "${staging}/screenrig" -cf - . \ | |
| | gzip -n -9 > "${RUNNER_TEMP}/screenrig-plugin.tar.gz" | |
| - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: screenrig-plugin | |
| path: ${{ runner.temp }}/screenrig-plugin.tar.gz | |
| if-no-files-found: error | |
| retention-days: 14 | |
| secrets: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install checksum-pinned Gitleaks | |
| env: | |
| GITLEAKS_VERSION: 8.30.1 | |
| GITLEAKS_SHA256: 551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb | |
| run: | | |
| install -d "${RUNNER_TEMP}/screenrig-tools/gitleaks" | |
| archive="${RUNNER_TEMP}/screenrig-tools/gitleaks.tar.gz" | |
| curl --proto '=https' --tlsv1.2 --fail --silent --show-error --location \ | |
| "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \ | |
| --output "${archive}" | |
| printf '%s %s\n' "${GITLEAKS_SHA256}" "${archive}" | sha256sum --check --status | |
| tar --extract --gzip --file "${archive}" \ | |
| --directory "${RUNNER_TEMP}/screenrig-tools/gitleaks" gitleaks | |
| chmod 0755 "${RUNNER_TEMP}/screenrig-tools/gitleaks/gitleaks" | |
| - name: Scan complete Git history for secrets | |
| run: >- | |
| "${RUNNER_TEMP}/screenrig-tools/gitleaks/gitleaks" git | |
| --redact --no-banner --config .gitleaks.toml . |