Template
A starter GitHub Actions workflow for a vibe-coded product
A copy-ready CI workflow: lint, types, tests, build, dependency review, CodeQL, and an OIDC deploy from main with no stored keys.
This is the workflow behind the safety net. It runs the checks on every pull request, reviews new dependencies, and scans the code. It deploys from main with short-lived AWS credentials and no stored keys. It assumes a Node.js project, but the shape is the same for any language.
The two files go into the repository as they are. Four repository settings sit outside the files, and the workflow can't switch them on by itself. The list below covers all four.
From the talk: Ship fast, break nothing: CI/CD for vibe-coded startups
The workflow
# .github/workflows/ci.yml
# Starter pipeline from the talk "Ship fast, break nothing" (netninjas.eu/events).
# Assumes a Node.js project whose package.json has lint, typecheck, test, and build scripts.
name: ci
on:
pull_request:
push:
branches: [main]
# Least privilege by default; jobs that need more ask for it.
permissions:
contents: read
# A new push to a pull request cancels its older run. Runs on main always finish.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
checks:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run lint
- run: npm run typecheck
- run: npm test
- run: npm run build
dependency-review:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/dependency-review-action@v5
with:
fail-on-severity: high
codeql:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v7
- uses: github/codeql-action/init@v4
with:
languages: javascript-typescript
- uses: github/codeql-action/analyze@v4
deploy:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: [checks, codeql]
runs-on: ubuntu-latest
environment: production
permissions:
contents: read
id-token: write # lets the job ask AWS for short-lived credentials (OIDC)
steps:
- uses: actions/checkout@v7
- uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: ${{ vars.AWS_DEPLOY_ROLE_ARN }}
aws-region: eu-central-1
- run: ./scripts/deploy.shAutomated dependency updates
Weekly update pull requests for packages and for the actions themselves. Minor and patch updates arrive together in one pull request.
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
groups:
minor-and-patch:
update-types: [minor, patch]
- package-ecosystem: github-actions
directory: /
schedule:
interval: weeklyFour settings the file can't set
- We protect main. A branch ruleset requires a pull request, plus passing checks and codeql jobs, before any merge.
- We turn on secret scanning with push protection. It sits in the repository's security settings, next to Dependabot alerts.
- We create the deploy role in AWS. GitHub's OIDC identity provider (token.actions.githubusercontent.com, audience sts.amazonaws.com), plus a role whose trust policy only accepts the subject repo:<owner>/<repo>:environment:production. Its ARN goes into the repository variable AWS_DEPLOY_ROLE_ARN.
- We add the production environment. An environment named production, limited to the main branch. Required reviewers add a human approval to each deploy.
Before relying on it
Two lines need local values: ./scripts/deploy.sh becomes the real deploy step, and eu-central-1 becomes the real region. On a private repository, CodeQL and dependency review need a GitHub Code Security licence, or Semgrep instead. On a public repository, both are free. Action versions move, and Dependabot keeps them current once its file is in place. Pinning each action to a full commit SHA is the stricter option.
What I leave out on purpose
I leave out matrix builds, self-hosted runners, and a separate staging pipeline. Each one solves a problem a small team rarely has on day one. I add them when the team needs them, not when a template suggests them.
Next step
Stuck on the OIDC role or the deploy step? I highly recommend a thirty-minute call with the repository open. We'll get the first green run together. What does your deploy step look like today?
Book a callThese takeaways are an engineer's reading of the rules and the tools. I wrote them to help teams decide what to build. They aren't legal advice. I recommend checking the current text with your own counsel before planning around a date or a threshold.
Other takeaways from this talk
Checklist
The 10-check vibe-coding safety net
Ten yes/no checks that turn a CI pipeline into the reviewer a solo founder or small team doesn't have. About a day of setup.
Worksheet
DORA metrics in 15 minutes
A one-page sheet to measure deployment frequency, lead time, change failure rate, and time to restore from your Git and deploy history.
Policy template
Agent permissions in one page
What an AI coding agent may and may not do in your repository, cloud, and data, with how to enforce each line. Ready to copy into a policy.
Let's talk.
A 30-minute call, no pitch. We look at your current setup, your stage, and the thing that's bothering you about it. I give a straight opinion on what to change, what to leave alone, and whether the problem is the one it looks like. What's the one thing in your stack you'd fix tomorrow?
Prefer email or phone? hello@netninjas.eu or +31 6 45984313