Dashboard

Set Up a GitHub Actions Pipeline With AI, Safely

AI writes a working workflow file in seconds. The problem is that working and safe are different tests, and the generated YAML tends to fail the second one.

Steve Jefferson
Steve Jefferson
Developer Advocate
9 October 20261 min read

You can set up a GitHub Actions pipeline with AI by describing your stack and asking for a workflow that runs install, lint, test and build. Then review the output for the settings models tend to skip: token permissions, action pinning, and concurrency. A workflow that goes green is not yet a workflow you should trust.

The generated YAML usually runs on the first try, which is the trap. Nothing visibly fails when the token has write access to everything or when a third-party action is pulled by a movable tag. The risk sits there quietly until someone exploits it.

Set up the GitHub Actions pipeline with a constrained prompt

Models write what is common, and common workflows on the internet are loose. Ask for the tight version up front.

text
Write a GitHub Actions workflow at .github/workflows/ci.yml.

Project: Node.js 22, npm, scripts: lint, test, build.
Triggers: pull_request to main, and push to main.

Requirements:
- Top-level permissions: contents read, nothing else.
- Cancel in-progress runs for the same branch or PR.
- Use npm ci, with npm caching through setup-node.
- Set a job timeout.
- Pin every third-party action to a full commit SHA, with the tag in a
  trailing comment. Leave a placeholder where you do not know the SHA
  and say so. Do not invent SHAs.
- Do not use pull_request_target.
- No secrets in this workflow.

The line about not inventing SHAs matters. A model will happily produce a plausible 40-character hash that points at nothing. You look the real one up yourself.

A baseline that passes review

yaml
name: ci

on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

permissions:
  contents: read

concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@<full-commit-sha> # v4
      - uses: actions/setup-node@<full-commit-sha> # v4
        with:
          node-version: 22
          cache: npm
      - run: npm ci
      - run: npm run lint
      - run: npm test
      - run: npm run build

Replace each placeholder with the commit SHA of the release you want, taken from that action's own repository. Do not copy one from a fork, since GitHub's hardening guide specifically says to verify that the SHA comes from the original repository.

The five-point review

Run this over any workflow an AI hands you, whether it is a ten-line CI file or a deploy pipeline.

  1. Token permissions. Is there a permissions block at the top? GitHub's security hardening guide recommends giving the token read-only access to repository contents by default and raising it only for the individual jobs that need more. If a job pushes or comments, grant that one job the one permission.

  2. Action pinning. Look at every uses: line. The same guide says pinning to a full-length commit SHA is the only way to treat an action as an immutable release, and that tags can be moved or deleted if an attacker gains access to the action's repository. First-party actions from GitHub carry less risk than unknown publishers, but the habit is cheap.

  3. Dangerous triggers. pull_request_target runs with access to repository secrets in the context of the base branch. Combined with checking out code from the pull request, it lets outside contributors run code with your secrets. If the model reached for it to make a comment bot work, push back and ask for a safer design.

  4. Secrets and logs. Search for echo near anything secret, and for env: blocks that put a token in the environment of every step. Scope secrets to the single step that needs them.

  5. Cost and runaway runs. Check for timeout-minutes and a concurrency group. Without them, a stuck job holds a runner for hours and every push to a branch stacks a fresh run on top of the last.

Let the AI do the second pass, too

After you review it yourself, paste the file back in and ask the model to audit it against that same five-point list, quoting the line for each finding. A fresh pass catches things the writing pass skipped, and it costs one request. It is a second opinion, not a replacement for the first.

For anything that touches deployment, keep humans on the approval step. The same logic as in how to sandbox an AI agent applies: give automation the least access that lets it do the job, and widen it deliberately.

Adjacent pieces worth generating the same way

A pipeline often builds a container. The method above carries over to prompting AI to write a Dockerfile: state the constraints first, then review for the known failure patterns. If you want a gate before code even reaches the pipeline, a pre-commit hook with an AI code reviewer catches problems locally. Shell steps inside workflows deserve the checks from writing a bash script you can trust. The AI coding tools guide covers which assistants handle multi-file configuration well.

FAQ

Can ChatGPT or Claude write a GitHub Actions workflow?

Yes, and for common stacks the result usually runs. Treat it as a draft: check the permissions, pin the actions, and add timeouts and concurrency before you merge it.

Why should I pin GitHub Actions to a commit SHA?

Tags can be moved or deleted if the action's repository is compromised. A full commit SHA is immutable, so what you reviewed is what runs. Dependabot can keep pinned SHAs up to date.

What permissions does GITHUB_TOKEN need for CI?

For a build-and-test job, read access to repository contents is usually enough. Grant extra permissions per job, only where a step needs to write.

Is it safe to let AI write my deploy workflow?

It is safe to let AI draft it. Review it with the five checks above, keep secrets scoped to single steps, and require a human approval for production deploys.

How did this land?

About the author

Steve Jefferson
Steve Jefferson

Developer Advocate

Steve builds something with Swarmz every week and writes up what worked, what broke, and what he'd do differently. Tutorials and hands-on guides are his lane.

Share

Get the next post in your inbox

One email a month. Product updates, engineering posts, and the best of Built with Swarmz.

I agree to receive emails about AI building tips and Swarmz product news. Unsubscribe any time.