diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..9ef24cf --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,5 @@ +# The action's steps and its workflows run with every caller's token and key: +# a change to them is reviewed by the maintainer, whoever opened it. +/action.yml @hblee12294 +/scripts/ @hblee12294 +/.github/ @hblee12294 diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..a891f9f --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +# The actions this action and its CI use are pinned to commits (a floating +# tag is whatever its owner's account pushes next); this is what moves the +# pins, one grouped pull request a week. +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + groups: + actions: + patterns: ['*'] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc4021f..1e488a7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,9 +3,8 @@ on: pull_request: push: branches: [main] -permissions: - contents: write # the dogfood commits the tracked base back after a push - pull-requests: write +# Nothing by default; the job names what it holds. +permissions: {} jobs: dogfood: # The action run on itself: record vos.so's own agents page, deliver the @@ -15,9 +14,13 @@ jobs: # branches never race for the same base, and the base main pushes from # is committed back right after. runs-on: ubuntu-latest + permissions: + contents: write # the dogfood commits the tracked base back after a push + pull-requests: write # the sticky comment steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + # Pinned to commits, moved by Dependabot (.github/dependabot.yml). + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: { node-version: 22 } - uses: ./ with: diff --git a/README.md b/README.md index beff245..9a217f8 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ jobs: key: ${{ secrets.VOS_API_KEY }} # mint one at vos.so/app/api ``` +Pin the action to a commit in your own workflow (`vosjs/action@ # v1`) and let Dependabot move it: the steps above run with your job's token and your key, and a floating tag is whatever its owner's account pushes next. + What lands on the pull request: > ### Release media for `pr-42` @@ -62,6 +64,7 @@ Start with the [launch-kit skill](https://github.com/vosjs/skills) (`npx skills | `tracking` | `media/vos.json` | Which vos the pushes version. After a push the action writes the new base back to this file; commit it (a step in your workflow, or a bot commit) or the next push is refused as a stale base. | | `comment` | `true` | Keep the sticky comment (needs `pull-requests: write`). | | `take` | runner temp | Where the take is recorded. | +| `cli` | the version this action was released with | The `@vosjs/cli` version it runs, an exact version. Pinned on purpose: an unpinned install would run whatever npm served that minute with the job's token and your key. Each release of the action moves the default. | Outputs: `kit`, `vos-id`, `version`, `watch-url`. diff --git a/action.yml b/action.yml index 9cdad8e..0a3c934 100644 --- a/action.yml +++ b/action.yml @@ -35,6 +35,12 @@ inputs: take: description: Where the take is recorded. default: ${{ runner.temp }}/take + cli: + description: >- + The @vosjs/cli version this action runs. Pinned, because an unpinned + install runs whatever npm served that minute, with the job's token and + your key; moved by the action's own releases. + default: '0.75.1' outputs: kit: @@ -50,43 +56,69 @@ outputs: description: The watch page (empty without a key). value: ${{ steps.push.outputs.watch-url }} +# Every input reaches a shell through `env`, never spliced into the script: +# an input is whatever the calling workflow put there, and a `${{ }}` inside +# `run` is substituted before the shell parses it. runs: using: composite steps: - name: name the release id: name shell: bash + env: + RELEASE: ${{ inputs.release }} + EVENT: ${{ github.event_name }} + PR_NUMBER: ${{ github.event.number }} + REF_NAME: ${{ github.ref_name }} run: | - if [ -n "${{ inputs.release }}" ]; then echo "release=${{ inputs.release }}" >> "$GITHUB_OUTPUT" - elif [ "${{ github.event_name }}" = "pull_request" ]; then echo "release=pr-${{ github.event.number }}" >> "$GITHUB_OUTPUT" - else echo "release=${{ github.ref_name }}" >> "$GITHUB_OUTPUT"; fi + if [ -n "$RELEASE" ]; then echo "release=$RELEASE" >> "$GITHUB_OUTPUT" + elif [ "$EVENT" = "pull_request" ]; then echo "release=pr-$PR_NUMBER" >> "$GITHUB_OUTPUT" + else echo "release=$REF_NAME" >> "$GITHUB_OUTPUT"; fi - name: install the vos CLI shell: bash - run: npm i -g @vosjs/cli + env: + CLI: ${{ inputs.cli }} + run: | + case "$CLI" in + *[!0-9.]*|'') echo "::error::cli must be an exact version, got '$CLI'"; exit 1 ;; + esac + npm i -g "@vosjs/cli@$CLI" - name: record the product shell: bash - run: vos record --actions "${{ inputs.actions }}" --out "${{ inputs.take }}" --strict --json + env: + ACTIONS: ${{ inputs.actions }} + TAKE: ${{ inputs.take }} + run: vos record --actions "$ACTIONS" --out "$TAKE" --strict --json - name: carry the committed cut onto the new footage if: hashFiles(inputs.doc) != '' shell: bash - run: vos plan "${{ inputs.take }}" --reuse --from "${{ inputs.doc }}" --json + env: + DOC: ${{ inputs.doc }} + TAKE: ${{ inputs.take }} + run: vos plan "$TAKE" --reuse --from "$DOC" --json - name: render the destination set id: deliver shell: bash + env: + TAKE: ${{ inputs.take }} + CHANNELS: ${{ inputs.channels }} + RELEASE: ${{ steps.name.outputs.release }} run: | - vos deliver "${{ inputs.take }}" --to "${{ inputs.channels }}" --release "${{ steps.name.outputs.release }}" --json | tee "${{ runner.temp }}/deliver.ndjson" - echo "kit=${{ inputs.take }}/kit" >> "$GITHUB_OUTPUT" + vos deliver "$TAKE" --to "$CHANNELS" --release "$RELEASE" --json | tee "$RUNNER_TEMP/deliver.ndjson" + echo "kit=$TAKE/kit" >> "$GITHUB_OUTPUT" - name: re-measure the kit from its bytes id: validate shell: bash + env: + TAKE: ${{ inputs.take }} run: | set +e - vos validate "${{ inputs.take }}/kit/kit.json" --json | tee "${{ runner.temp }}/validate.ndjson" + vos validate "$TAKE/kit/kit.json" --json | tee "$RUNNER_TEMP/validate.ndjson" echo "status=$?" >> "$GITHUB_OUTPUT" exit 0 @@ -96,20 +128,27 @@ runs: shell: bash env: VOS_API_KEY: ${{ inputs.key }} + TAKE: ${{ inputs.take }} + TRACKING: ${{ inputs.tracking }} + RELEASE: ${{ steps.name.outputs.release }} + REPO: ${{ github.repository }} + EVENT: ${{ github.event_name }} + SHA: ${{ github.sha }} + ACTION_PATH: ${{ github.action_path }} run: | - if [ -f "${{ inputs.tracking }}" ]; then cp "${{ inputs.tracking }}" "${{ inputs.take }}/vos.json"; fi - vos push "${{ inputs.take }}" --label "${{ steps.name.outputs.release }} launch" --note "Release media from ${{ github.repository }} (${{ github.event_name }} ${{ github.sha }})" --yes --json | tee "${{ runner.temp }}/push.ndjson" - node "${{ github.action_path }}/scripts/outputs.mjs" "${{ runner.temp }}/push.ndjson" >> "$GITHUB_OUTPUT" + if [ -f "$TRACKING" ]; then cp "$TRACKING" "$TAKE/vos.json"; fi + vos push "$TAKE" --label "$RELEASE launch" --note "Release media from $REPO ($EVENT $SHA)" --yes --json | tee "$RUNNER_TEMP/push.ndjson" + node "$ACTION_PATH/scripts/outputs.mjs" "$RUNNER_TEMP/push.ndjson" >> "$GITHUB_OUTPUT" # The push moved the base: the take's vos.json now names the version # it created. Write it back to the tracking path so the workflow can # commit it, or the next push is refused as a stale base. - if [ -n "${{ inputs.tracking }}" ] && [ -f "${{ inputs.take }}/vos.json" ]; then - mkdir -p "$(dirname "${{ inputs.tracking }}")" - cp "${{ inputs.take }}/vos.json" "${{ inputs.tracking }}" + if [ -n "$TRACKING" ] && [ -f "$TAKE/vos.json" ]; then + mkdir -p "$(dirname "$TRACKING")" + cp "$TAKE/vos.json" "$TRACKING" fi - name: attach the kit - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: release-kit-${{ steps.name.outputs.release }} path: ${{ inputs.take }}/kit @@ -127,7 +166,8 @@ runs: PR: ${{ github.event.number }} RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} ARTIFACT: release-kit-${{ steps.name.outputs.release }} - run: node "${{ github.action_path }}/scripts/comment.mjs" + ACTION_PATH: ${{ github.action_path }} + run: node "$ACTION_PATH/scripts/comment.mjs" - name: the kit failed its own verifier if: steps.validate.outputs.status != '0' diff --git a/test/actions.json b/test/actions.json index 32ac1cd..cc1b268 100644 --- a/test/actions.json +++ b/test/actions.json @@ -9,6 +9,6 @@ { "id": "scroll", "do": "scroll", "dy": 700 }, { "id": "settle", "do": "wait", "ms": 1200 }, { "id": "section", "do": "hover", "selector": "h2", "ms": 900 }, - { "id": "end", "do": "wait", "ms": 6000 } + { "id": "end", "do": "wait", "ms": 10000 } ] }