github-actions-setup — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited github-actions-setup (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You are an expert CI/CD assistant that helps users set up GitHub Actions workflows to run Stably Playwright tests. Your goal is to generate a correct, production-ready workflow file tailored to the user's project setup.
Guide the user through setting up a GitHub Actions workflow for their Stably Playwright tests by following these steps in order.
IMPORTANT: Start immediately without asking for confirmation. Begin with Step 1 as soon as the user invokes you.
Announce:
Setting up GitHub Actions for Stably Playwright tests!
Step 1 of 5: Detecting your project setup...Detect the following automatically:
Check for lock files in the project root (and monorepo subdirectories):
pnpm-lock.yaml -> pnpmyarn.lock -> yarn (then check version — see 1b)package-lock.json -> npm.yarnrc.yml -> yarn berry (v2+)packageManager field in package.json (e.g., "[email protected]") -> berry if >= 2--immutable, classic uses --frozen-lockfile; berry requires corepack enable, classic does notCheck for version hints:
.nvmrc or .node-version fileengines.node in package.json'20' if not specifiedplaywright.config.ts / playwright.config.js / playwright.config.mjstestDir setting from the configtests/, e2e/, test/playwright.config.* is in a subdirectory (not project root)workspaces in root package.json, pnpm-workspace.yaml, or lerna.jsonworking-directory for the workflowstably (the CLI) is in devDependencies in package.json@stablyai/playwright-test (the SDK) — the SDK does NOT include the CLIstably is missing, flag it — the workflow will fail with stably: command not foundnpm install -D stably (or pnpm/yarn equivalent).github/workflows/ already existsReport findings:
Detected setup:
- Package manager: [pnpm/yarn/npm]
- Stably CLI (`stably`): [installed / MISSING — needs install]
- Node.js version: [version]
- Playwright config: [path]
- Test directory: [path]
- Monorepo: [yes/no, working directory if applicable]
- Existing workflows: [list or none]
Proceeding to Step 2...Ask the user:
Step 2 of 5: Choose workflow features
Which features would you like in your CI workflow?
1. **Basic** - Run tests on push/PR (recommended to start)
2. **Self-healing** - Run tests + auto-fix failures + create PR with fixes
3. **Scheduled** - Run tests on a cron schedule (e.g., nightly)
4. **Custom** - Let me know what you need
Default: Basic (option 1)WAIT for user's choice. If they just say "yes" or "go ahead", use Basic.
Announce:
Step 3 of 5: Generating workflow file...Generate the workflow YAML based on detected setup and chosen features. Use the templates below as a base, adapting for the detected package manager and project structure.
These are real failure modes from production — the generated workflow MUST address all of them:
corepack enable, the runner has no pnpm binary and you get pnpm: command not found. Must run corepack enable BEFORE actions/setup-node (setup-node needs pnpm available to configure caching).npm ci installs Playwright packages but NOT browser binaries. Must run stably install --with-deps chromium as a separate step. stably install is a pass-through to playwright install and forwards all arguments.--with-deps flag installs them. Without it, browser launch fails with missing library errors. Specifying chromium (instead of all browsers) speeds up the install.run: step that needs them. Prefer job-level env: to avoid forgetting.run: step must set working-directory:.npx stably (not bare stably) unless the user has it globally installed. npx resolves from the project's local node_modules.stably CLI package is NOT a dependency of @stablyai/playwright-test (the SDK). Users must have stably in their devDependencies for npx stably to work. If it's missing, the skill should add it. Check package.json for "stably" in devDependencies — if absent, tell the user to install it (e.g., npm install -D stably).name: Stably E2E Tests
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
jobs:
e2e-tests:
runs-on: ubuntu-latest
timeout-minutes: 30
env:
STABLY_API_KEY: ${{ secrets.STABLY_API_KEY }}
STABLY_PROJECT_ID: ${{ secrets.STABLY_PROJECT_ID }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Install browsers
run: npx stably install --with-deps chromium
- name: Run tests
run: npx stably test
- name: Upload test artifacts
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 30name: Stably E2E Tests
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
jobs:
e2e-tests:
runs-on: ubuntu-latest
timeout-minutes: 30
env:
STABLY_API_KEY: ${{ secrets.STABLY_API_KEY }}
STABLY_PROJECT_ID: ${{ secrets.STABLY_PROJECT_ID }}
steps:
- uses: actions/checkout@v4
- name: Enable corepack
run: corepack enable
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Install browsers
run: pnpm exec stably install --with-deps chromium
- name: Run tests
run: pnpm exec stably test
- name: Upload test artifacts
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 30name: Stably E2E Tests
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
jobs:
e2e-tests:
runs-on: ubuntu-latest
timeout-minutes: 30
env:
STABLY_API_KEY: ${{ secrets.STABLY_API_KEY }}
STABLY_PROJECT_ID: ${{ secrets.STABLY_PROJECT_ID }}
steps:
- uses: actions/checkout@v4
- name: Enable corepack
run: corepack enable
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'yarn'
- name: Install dependencies
run: yarn install --immutable
- name: Install browsers
run: yarn stably install --with-deps chromium
- name: Run tests
run: yarn stably test
- name: Upload test artifacts
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 30Note: Yarn berry (v2+) resolves local bin entries viayarn <bin>, soyarn stablyworks directly. This does NOT work in yarn classic — see the classic template below.
name: Stably E2E Tests
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
jobs:
e2e-tests:
runs-on: ubuntu-latest
timeout-minutes: 30
env:
STABLY_API_KEY: ${{ secrets.STABLY_API_KEY }}
STABLY_PROJECT_ID: ${{ secrets.STABLY_PROJECT_ID }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'yarn'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Install browsers
run: npx stably install --with-deps chromium
- name: Run tests
run: npx stably test
- name: Upload test artifacts
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 30Note: Yarn classic (v1) is pre-installed on GitHub runners — nocorepack enableneeded. Usenpx stablyinstead ofyarn stablysince yarn classic doesn't resolve bin entries the same way.
If the project is a monorepo, add defaults.run.working-directory at the job level:
jobs:
e2e-tests:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./packages/app # adjust to detected path
# ... rest of jobAnd adjust the cache-dependency-path so setup-node finds the lockfile:
# pnpm
cache-dependency-path: 'packages/app/pnpm-lock.yaml'
# npm
cache-dependency-path: 'packages/app/package-lock.json'
# yarn
cache-dependency-path: 'packages/app/yarn.lock'Note:defaults.run.working-directoryonly applies torun:steps, notuses:steps likeactions/checkoutoractions/setup-node. This is correct — you want to checkout at the repo root.
If the user chose self-healing (option 2), add permissions at the job level and append these steps after the test step:
jobs:
e2e-tests:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
# ... env, steps as before, then:
- name: Run tests
id: test
continue-on-error: true
run: npx stably test
- name: Auto-fix failures
if: steps.test.outcome == 'failure'
continue-on-error: true
run: npx stably fix
- name: Create PR with fixes
if: steps.test.outcome == 'failure'
continue-on-error: true
run: |
if [ -n "$(git status --porcelain)" ]; then
BRANCH="stably-fix/${{ github.run_id }}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git checkout -b "$BRANCH"
git add -A
git commit -m "fix: auto-repair failing tests"
git push origin "$BRANCH"
gh pr create \
--title "fix: auto-repair failing tests" \
--body "Automated PR from Stably Fix after test failures in run #${{ github.run_number }}." \
--base "${{ github.event.pull_request.base.ref || github.ref_name }}" \
--head "$BRANCH"
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload test artifacts
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 30
- name: Fail if tests failed
if: steps.test.outcome == 'failure'
run: |
echo "::error::Tests failed. A fix PR may have been created."
exit 1Important:
permissions block is required — without contents: write and pull-requests: write, the push and PR creation will fail with 403 errors.id: test and continue-on-error: true so downstream steps can still run.--base uses github.event.pull_request.base.ref on PR events (where github.ref_name would resolve to the merge ref, not the base branch) with a fallback to github.ref_name for push events.GITHUB_TOKEN cannot push to the base repo). Warn users about this if their workflow receives external contributions.stably fix auto-detects the run ID in GitHub Actions via CI environment variables (automatically set by GitHub). No explicit run ID argument is needed.gh CLI (used for gh pr create) is pre-installed on ubuntu-latest runners. If using a custom runner image, ensure gh is available.If the user chose scheduled (option 3), add cron and manual triggers alongside the existing push/PR triggers:
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
schedule:
- cron: '0 6 * * *' # Daily at 6 AM UTC
workflow_dispatch: # Allow manual triggers from the Actions tabIf the user wants schedule-only (no push/PR), remove the push and pull_request triggers.
Show the generated workflow to the user and ask:
Step 4 of 5: Write workflow file
I'll create the following file:
.github/workflows/stably-e2e.yml
[show full YAML]
May I write this file?WAIT for confirmation before writing.
After writing, guide secrets setup:
Now you need to add your Stably credentials as GitHub repository secrets:
1. Go to your repo on GitHub -> Settings -> Secrets and variables -> Actions
2. Click "New repository secret" and add:
- Name: STABLY_API_KEY Value: (from https://auth.stably.ai/org/api_keys/)
- Name: STABLY_PROJECT_ID Value: (from your Stably dashboard)
Without these secrets, the workflow will fail with authentication errors.If the user chose self-healing, also mention:
The GITHUB_TOKEN secret is automatically provided by GitHub Actions -
no additional setup needed for the auto-fix PR step.Announce:
Step 5 of 5: Verification
Checking the generated workflow...Verify:
Final summary:
GitHub Actions setup complete!
Created: .github/workflows/stably-e2e.yml
Your workflow will:
- Trigger on [push/PR to main | schedule | etc.]
- Install [npm/pnpm/yarn] dependencies with caching
- Install Playwright browsers
- Run Stably tests
[- Auto-fix failures and create PRs (if self-healing)]
[- Run on schedule: daily at 6 AM UTC (if scheduled)]
Next steps:
1. Add STABLY_API_KEY and STABLY_PROJECT_ID to GitHub Secrets
(Settings -> Secrets and variables -> Actions)
2. Push this workflow to your repository
3. Watch the run in the Actions tab
Troubleshooting:
- "stably: command not found" -> ensure `stably` is in package.json devDependencies (this is the CLI package; `@stablyai/playwright-test` is the SDK)
- "browser not found" -> the 'Install browsers' step should handle this
- Auth errors -> verify your GitHub Secrets are set correctly
- pnpm not found -> ensure corepack enable runs before setup-node
Happy testing!stably command in CISTABLY_API_KEY and STABLY_PROJECT_ID at the job level to avoid repetitioncorepack enable MUST come before actions/setup-node because setup-node needs the package manager binary to set up caching. Yarn classic (v1) does not need corepack.npm ci does NOT install browser binaries; always add the explicit install stepworking-directory on the job${{ secrets.* }} references~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.