All jobs

Set Up GitHub Actions CI for an Express App

Yes. An agent reads your Express repo, adds a GitHub Actions workflow that lints, tests against Postgres and builds, and fixes it until it passes.

Run this on RushIn a Project that has your repository.

What the agent does

The agent starts from what the repository already declares. In an Express API like gothinkster/node-express-realworld-example-app, package.json has three scripts, start, build and test, and each of them calls nx: the project is an Nx 17.2.6 workspace with one application, api, described in project.json. The lockfile is package-lock.json at lockfileVersion 3, there is no engines field and no .nvmrc, and @types/node is pinned to 18.16.9, so the agent pins Node 18 in the workflow and says in the pull request why.

Then it reads how the project is built and tested. project.json defines build with the @nx/esbuild executor from src/main.ts into dist/api, lint with @nx/eslint:lint over ./src, and test with @nx/jest:jest reading jest.config.ts, which runs ts-jest over src/**/*.spec.ts and *.test.ts. The five unit tests under src/tests/services/ mock Prisma with jest-mock-extended through src/tests/prisma-mock.ts, so they need no database. The e2e project is different: e2e/jest.config.ts has a global setup and a spec that calls the running server with axios, so it needs the API up and a database behind it.

The database is the part the workflow has to get right. src/prisma/schema.prisma declares a postgresql datasource read from DATABASE_URL, with migrations under src/prisma/migrations/ and a seed script in the prisma block of package.json. The README lists DATABASE_URL, JWT_SECRET and NODE_ENV as the required variables. So the workflow adds a postgres service container, sets DATABASE_URL to it, runs npx prisma generate and npx prisma migrate deploy before the tests, and sets a throwaway JWT_SECRET.

The workflow it writes at .github/workflows/ci.yml runs on pull requests and on pushes to the default branch, checks out, sets up Node 18 with actions/setup-node caching keyed on package-lock.json, runs npm ci, then npx nx lint api, npx nx test api --configuration=ci for coverage, npx nx build api, and the migrations against the service. The agent pushes the branch and watches the workflow run on its own pull request; when a step fails, it reads the log, fixes the cause and pushes again. In this repository it also notes that e2e/src/server/server.spec.ts expects a Hello API body that src/main.ts does not send, and leaves the e2e project out of the required job with that reason in the description rather than editing the test to pass.

Start it with one API call

POST https://api.prix.dev/o/{org}/sessions with this body:

{
  "agent": "claude",
  "input": "Add a GitHub Actions workflow at .github/workflows/ci.yml that runs on every pull request and on pushes to the default branch. Read package.json, the lockfile, project.json, nx.json, jest.config.ts and prisma/schema.prisma first: pin the Node version the repository implies, use the package manager the lockfile implies with caching keyed on that lockfile, and run the lint, test and build targets the project defines. If the tests or the app need a database, add a postgres service container, point DATABASE_URL at it, and run prisma generate and prisma migrate deploy before the tests, with any other required variables set to throwaway values. Do not touch existing workflow files. Open a pull request and make sure the new workflow passes on it; if a step fails, fix the cause and push again. If an existing test cannot pass as written, leave it out of the required job and explain why in the pull request instead of changing the test.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
  1. Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
  2. Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
  3. Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

What comes back

What comes back is a pull request on its own branch adding .github/workflows/ci.yml and nothing else unless a script was missing. The workflow has one job with a postgres service, Node 18 from actions/setup-node with npm caching, npm ci, the Prisma generate and migrate steps with DATABASE_URL pointing at the service, and the three Nx targets in order: lint, test with the ci configuration, build. The job's checks show green on the pull request itself before the agent finishes.

The description explains each pin: Node 18 because @types/node is 18.16.9 and nothing else declares a version, npm because the lockfile is package-lock.json, the service container because the Prisma datasource is Postgres. It also says what was left out and why, such as the e2e project whose spec expects a response body the server does not send.

A reviewer checks that the workflow runs the same commands they run locally, that no secret was committed (the JWT_SECRET in the workflow is a throwaway string for tests only), and that the service's Postgres major matches what production uses. The session read returns the repository and the pull request, and the transcript keeps every workflow run the agent watched, including any failed attempt and the fix that followed.

Run it on every new repository

Start one run per repository without CI from your own server: POST /o/{org}/sessions with this prompt and that repository in resources, one call each. GET /o/{org}/github lists every repository the Rush GitHub App installation can reach, so a script can find the ones with no .github/workflows/ directory and start a run for each. Each run works in its own sandbox and on its own branch.

Give the key a webhook_url and each run POSTs run.completed with its session_url when the turn finishes, so the pull request links collect on your side without polling. A key has at most max_concurrent runs in progress at once, 4 by default, so a batch over many repositories queues past that.

The use case this job follows, with its automation and trigger: Hand off from your terminal.

Why run it on Rush?

A workflow is only done when it has passed on a real pull request, and that loop of push, wait, read the log, fix, push again is the tedious part. On Rush the agent runs that loop itself in its own sandbox, with the repository's own Node, npm and Postgres, and every attempt stays in the transcript. The reviewer sees the first failure and the fix rather than a workflow that was never run.

The details that break CI are all in files: the Nx targets, the Prisma datasource, the missing engines field, the e2e spec that disagrees with the server. The agent reads them in the sandbox and writes the workflow from what it found, not from a template, and the pull request says which file each choice came from.

Frequently asked questions

Will it change my existing workflow files?

No. The prompt says not to touch existing workflows, so the agent adds ci.yml beside them. If an existing workflow already covers lint or tests, say so in the prompt and the new one is scoped to what is missing.

The tests need a database. How does the workflow get one?

With a service container. The agent reads the Prisma datasource provider, adds a postgres service with a health check to the job, sets DATABASE_URL to it and runs prisma migrate deploy before the tests. Unit tests that mock Prisma, like the ones under src/tests/services/, run without it either way.

Does it work with Nx, Turborepo or a plain npm scripts repository?

Yes. The agent runs whatever the repository's scripts call. In the RealWorld example that is npx nx lint api, npx nx test api and npx nx build api; in a plain repository it is npm run lint, npm test and npm run build.

Which Node version will it pin?

The one the repository implies, in this order: .nvmrc, engines.node in package.json, then the @types/node major. The RealWorld example has only the last, 18.16.9, so the workflow pins Node 18 and the description says that is the reason.

What happens if a test fails for a reason unrelated to CI?

The agent does not edit the test to make it pass. It leaves that test out of the required job, names it in the pull request with the reason, and the workflow stays green on what is actually correct. You can reply to the session with a follow-up to fix the test as well.