feat(workflows): host the reusable GitHub workflows in this repo - #120
Draft
metalwarrior665 wants to merge 8 commits into
Draft
feat(workflows): host the reusable GitHub workflows in this repo#120metalwarrior665 wants to merge 8 commits into
metalwarrior665 wants to merge 8 commits into
Conversation
Moves the contents of apify-store/github-actions-source here, so a change that spans a CLI feature and the workflow calling it is one PR against one branch instead of two repos with a manual ref dance between them. Consumers pin the `@v1` major tag rather than `@master`, and the setup action installs `apify-test-tools@>=<floor>` (from .github/workflows-min-package-version) instead of `@latest`. That resolves to the same newest stable in the normal case, but makes a workflow's package requirement explicit. The release cadences stay independent, because most changes only touch one side: - workflow-only change: merge, `v1` moves, live, no npm release - package-only change: merge and release when ready, workflows untouched - workflow calling a new CLI feature: raise the floor in the same PR. On merge the `v1` move is held with a warning until that version is on npm, so consumers keep running the previous workflows instead of calling a CLI that doesn't exist yet. A stable release moves the tag; `manual_move_major_tag` is the escape hatch. Also: - run-with-apify-tokens.mjs moves to .github/scripts/, next to the other CI helper and out of eslint's path; the action's `scripts-path` output follows it - pass github.head_ref/base_ref through the environment in pr-build-test, since branch names are attacker-controlled on fork PRs and actionlint gates master here - prettier formatting on the imported files, which husky enforces here Refs in the consumer snippets in the README were still `@new_master` and are updated along with the repo path.
actionlint gates master here and the action wrapper runs shellcheck, which the old repo's CI did not, so this SC2086 came in with the import. Unquoted it would word-split if the runner ever pointed $GITHUB_OUTPUT at a path with spaces.
…ctions-package-ep3lzw
Catches the merged copy up with the four commits that landed on github-actions-source master after the import (#57, #59, #60, #63), all of which built the claude-review action. Two new files, nothing else changed upstream. `review.yaml` fetches its instructions over HTTP rather than from a checkout, because a reusable workflow runs with the caller's repo checked out and never gets its own, so the URL had to follow the move to this repo. Its `prompt-ref` default moves from `master` to `v1`: consumers call the workflow at `@v1`, and defaulting the prompt to master would run released workflows against unreleased instructions, which is the skew the tag gate exists to prevent. Also drops `RUN_PLATFORM_TESTS` from pr-build-test. Master removed it in #122 in favour of gating on `TESTER_APIFY_TOKEN`, which that step already sets, so after merging master the variable was config nothing reads. Two notes on the checks: - .github/actionlint.yaml ignores two errors on review.yaml. actionlint bakes in a snapshot of popular actions' interfaces from when the pinned version shipped, and claude-code-action has grown since, so it flags `display_report` and the `conclusion` output as undefined. Both are declared in the action's action.yml at @v1 — verified before suppressing, and the patterns name those two symbols so unrelated bad inputs and outputs in that file still fail. - .github/review-prompt.md is prettier-ignored. Prettier collapses the nested bullet list under "do not visit, fetch, infer, or evaluate the following external links" into one run-on line, changing what the model is told. Keeping it byte-identical also makes re-syncing it a plain copy. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SkUZADZ6gzWW4GE6CFMreM
… the refs Cuts the major tag as `v0` rather than `v1`, since the package is on 0.x and will keep releasing 0.x for a while. Nothing in the gate logic reads the number, so this is only the tag name and the refs that repeat it. Keeping consumers on `@master` until the package hits 1.0 was the alternative, and it reopens the gap this was built to close: the floor gate has teeth only because consumers track a tag that can be held. On `@master` a workflow calling an unreleased CLI feature ships on merge and fails in every consumer's CI, instead of simply not shipping. The tag tracks the workflows' contract, not the package version — they move independently on purpose, so `v0` is expected to outlive the package reaching 1.0. Bump it when a workflow breaks its callers, not when the package does. Adds check-major-tag-refs.mjs to _check_code, because `uses:` cannot take an expression, so the tag is repeated in all seven refs into this repo plus the README snippets people copy. Missing one during a bump is silent in the case that matters: right after a bump both tags exist, so workflows called at the new tag pull the composite action from the old one and run a stale version of it without failing. The check compares every self-reference and review.yaml's prompt-ref default against MAJOR_TAG and names the file and line that disagree. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SkUZADZ6gzWW4GE6CFMreM
GitHub only reads workflow files at the top level of .github/workflows, so the workflows other repos call sit in the same directory as this repo's own CI with nothing distinguishing them. The prefix makes the boundary readable: `public_` is the API other repos depend on, `_` is internal plumbing, `on_`/`manual_` are this repo's own triggers. Renamed: public_pr-build-test, public_platform-tests, public_push-build-latest, public_claude, public_review, public_platform-tests-claude-investigate-and-fix. Breaking for anyone already calling these by path, which today is nobody: the v0 tag does not exist yet and consumers still point at the old repo. Doing it now costs nothing; after the first tag it would cost a major bump, since a filename is baked into every consumer's `uses:` line. CONTRIBUTING says so where the convention is introduced. Two references would have broken quietly rather than loudly: - .github/actionlint.yaml keys its ignores by path, so a stale key silently stops suppressing and the claude-code-action false positives come back. Verified by pointing the key at the old name and watching both errors return. - check-major-tag-refs.mjs reads review.yaml by path to check its prompt-ref default; a stale path would have downgraded that to a soft "could not read". The separators are now mixed (public_platform-tests), since the prefix is underscore-style and the imported names are hyphenated. Left as-is because the rest of the filename is the part consumers type. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SkUZADZ6gzWW4GE6CFMreM
…t a floor bump The floor is a hand-written declaration, so the tag hold only protects consumers if someone remembers to raise it. Forgetting is silent at merge time and loud everywhere else: the tag moves, the workflow goes live, and it calls a CLI that is not on npm, breaking every consumer's CI at once. The check fires only when a single PR touches both sides — a `public_` workflow or the composite action, and `bin/`, `lib/` or `index.ts` — and no floor bump. `lib/` counts because the platform tests import it, so a workflow can depend on its behaviour as much as on a CLI flag. Deliberately scoped to one PR. A workflow could also start using something from an earlier unreleased PR, which this will not see. Catching that means comparing against the floor's release tag, which flags every workflow edit made while any package change sits unreleased — far more noise than a case that needs someone to land a CLI change and then sit on it. Unrelated changes do land in one PR, so `no-floor-bump-needed` skips the check rather than leaving no way past it. The failure message names both halves of the diff and spells out both exits. Verified against ten path combinations, including the real diff of this branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SkUZADZ6gzWW4GE6CFMreM
Syncs github-actions-source#62, the one commit that landed there since the last sync. Gives the investigate phase read-only access to the failing run through the Apify MCP server, so it can read the run, its log and its storages instead of working from workflow logs alone, and pins claude-code-action to a SHA. Applied to the renamed public_ file; the patch landed unchanged otherwise. Documents the new TESTER_APIFY_TOKEN_READ_ONLY in the README secrets table, since it is consumer-facing: the workflow declares it `required: true`, so a repo calling this workflow without that secret set will fail the call. Upstream has it on master already, which is live, so this is not new breakage — but repos that pick it up when they migrate to @v0 need the secret in place first. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SkUZADZ6gzWW4GE6CFMreM
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR introduces a complete set of reusable GitHub workflows and supporting infrastructure that consumer repositories can use for testing, building, and releasing their Actors.
Summary
The package now includes production-ready reusable workflows alongside the CLI, enabling consumer repos to standardize their CI/CD pipelines. These workflows handle platform testing, PR validation, releases, and Claude-powered automated investigation and fixes for failing tests.
Key Changes
Reusable Workflows (
.github/workflows/):pr-build-test.yaml: Runs unit tests and platform tests on pull requestsplatform-tests.yaml: Scheduled platform test runs with Slack reportingpush-build-latest.yaml: Builds and releases Actors on master pushclaude.yaml: Responds to@claudementions to implement fixes via Claude Codeplatform-tests-claude-investigate-and-fix.yaml: Two-phase workflow that uses Claude to investigate failing tests and automatically open issues and PRs_move_major_tag.yaml: Manages the floating@v1tag, only moving it when the required package version is publishedmanual_move_major_tag.yaml: Escape hatch for manual tag managementGitHub Actions (
.github/actions/):checkout-restore-dependencies/action.yaml: Composite action for checkout, Node setup, and dependency caching with npm token isolationHelper Scripts (
.github/scripts/):run-with-apify-tokens.mjs: Securely passes only required Actor tokens to CLI commands, preventing secret leakage tonode_modulesConfiguration:
.github/workflows-min-package-version: Declares the minimum CLI version required by the workflows, gating tag movement until that version is publishedDocumentation:
README.mdwith workflow usage examples, secret handling details, and versioning guidanceCONTRIBUTING.mdto document the workflows as a third component of the packageNotable Implementation Details
Secret Isolation: Secrets are passed only to the steps that need them, never as job-wide environment variables. The
run-with-apify-tokens.mjsscript readsapify-test-tools.config.jsonto determine which Actor tokens to pass, preventing accidental exposure.Versioning Strategy: Consumer repos pin workflows to
@v1(a floating major tag), not@master. The tag only moves when the declared minimum package version is published on npm, preventing workflows from calling unreleased CLI features.Claude Integration: The
platform-tests-claude-investigate-and-fix.yamlworkflow chains investigation and fix phases as job dependencies rather than label triggers, working around GitHub's limitation that scheduled runs cannot trigger other workflows.Backward Compatibility: The
platform-tests.yamlworkflow supports both the deprecatedsubtestinput and the newtest-files-globinput for gradual migration.https://claude.ai/code/session_01SkUZADZ6gzWW4GE6CFMreM