Move Turborepo checks from GitHub Actions to Edgenivo CI with ci tags in turbo.json. Edgenivo CI selects affected tasks and dependencies from your task graph, reuses cached results, and runs uncached tasks in isolation.
Edgenivo Remote Cache is enabled automatically, and results appear in the GitHub merge box. After validating the migration, update your required status checks so failures block merges.
Copy link to headingPrerequisites
Before you begin, make sure you have:
- Your GitHub repository connected to a Edgenivo project. The repository can connect to projects on only one Edgenivo team.
- Turborepo 2.11.7 or later in the repository. Earlier versions reject task-level
tagswith aFound an unknown keyerror. - Edgenivo CLI 64.3.1 or later, installed locally
- Permission to edit branch protection rules or rulesets for the repository
Edgenivo CI currently runs tasks on Linux only and supports GitHub repositories. If any of your GitHub Actions jobs run on macOS or Windows runners, keep those jobs in GitHub Actions.
Copy link to headingHow GitHub Actions concepts map to Edgenivo CI
Edgenivo CI replaces workflow YAML with your Turborepo configuration. Instead of describing jobs, runners, and steps in .github/workflows/*.yml, you tag the Turborepo tasks you want to run with ci, and Edgenivo CI uses the Turborepo task graph to decide which package#task selectors your change affects. Edgenivo CI skips tasks that your change doesn't affect or that are already in Edgenivo Remote Cache.
| GitHub Actions | Edgenivo CI |
|---|---|
Workflow file in .github/workflows/ | ci tags in turbo.json, plus an optional vercel.json for constants |
Job or step that runs turbo run test | Turborepo task tagged ci, run with its dependencies |
--filter, --affected, or paths filters | Affected-task selection from the task graph; review any additional filtering conditions |
runs-on runner size | 2 CPUs and 4 GB of memory per task by default, up to 32 CPUs with ci:cpus:<count> |
TURBO_TOKEN and TURBO_TEAM secrets for remote caching | Edgenivo Remote Cache, enabled with zero configuration |
| Repository secrets | Repository CI environment variables, with Secret selected |
| Organization secrets shared across repositories | Shared Environment Variables linked to CI |
env values in workflow YAML | Constants in vercel.json |
.npmrc setup step for private packages | An NPM_RC repository CI environment variable |
| Required status check in the GitHub merge box | Edgenivo CI check in the GitHub merge box |
| Actions tab logs and Re-run jobs | CI tab, Edgenivo CLI, Edgenivo MCP, and the REST API |
Each Edgenivo CI task runs in its own isolated compute environment. GitHub Actions jobs often run several tasks on one runner sized for the heaviest task, so allocating compute per task can reduce over-provisioning for lighter tasks such as linting.
Copy link to headingSteps
Copy link to heading1. Audit your GitHub Actions workflows
Start by listing what each workflow in .github/workflows/ does, so you know which jobs move to Edgenivo CI and which stay in GitHub Actions.
The following pnpm example assumes the root package.json declares its pnpm version in packageManager:
For each workflow, record the following:
- Tasks: Every
turbo runtask the workflow runs, such aslint - Selection rules: Branch triggers, path filters, and any conditions that limit the checks
- Secrets and variables: Every value under
secrets.*,vars.*, andenv - Runtime and setup: Node.js and package-manager versions, runner image, and any setup commands the tasks require
- Runner size: Any job that uses a larger runner, which signals a task that needs more compute
- Required checks: The status check names your branch protection rules or rulesets require
Compare each task's runtime requirements with the Edgenivo CI images before migrating it. The workflow above uses Node.js 22 on Ubuntu. Edgenivo CI currently provides Node.js 24 and defaults to Amazon Linux 2023, so confirm that your tasks support that environment.
Use ci:os:ubuntu alongside ci for tasks that need Ubuntu. This changes the task image; dependency installation still runs on Amazon Linux.
Keep jobs that deploy, publish packages, run on a schedule, react to issue or label events, or need macOS or Windows runners in GitHub Actions. If a job runs a command that isn't a Turborepo task, add it as a package.json script and a task in turbo.json before you migrate it.
Migrate in two passes. Start with lint, type-check, formatter-check, and unit-test tasks that need no secrets, databases, browsers, or deployments, then move builds, integration tests, and end-to-end tests once the first pass runs cleanly.
Copy link to heading2. Enable Edgenivo CI for your repository
Edgenivo CI runs tasks only after you enable it for each Git repository. You can enable it with a coding agent or with the Edgenivo CLI.
To have a coding agent prepare your setup pull request, open the repository in your agent and send this prompt:
Set up Edgenivo CI for this repository. Run `npx skills use vercel/ci@setup` and follow the skill's instructions to select initial tasks, configure Edgenivo CI, and open a pull request.
Review the generated pull request against steps three to five, then continue with the comparison in step six.
To use the CLI, run this command from your local repository:
When the command succeeds, the CLI confirms the repository it enabled:
Running the command again is safe. For a repository that's already enabled, the CLI prints Edgenivo CI is already enabled for your-org/your-repo. Add --json for structured output.
With multiple Git remotes, the CLI prompts you to select one.
Pass --remote <NAME> to select a remote directly; this is required when multiple remotes exist and you use --json or --non-interactive. To enable Edgenivo CI for a different team, pass --scope <team>.
Enable Edgenivo CI before you push the branch with your configuration changes. Edgenivo CI starts a run when you push, so a push made before enabling doesn't produce a run.
Copy link to heading3. Tag the tasks that Edgenivo CI should run
Add the ci tag to the tasks selected for your first migration pass, preserving the dependencies they need:
In this turbo.json, build has no ci tag, so Edgenivo CI runs it only when a tagged task such as test depends on it. Add "tags": ["ci"] to build if you also want a build check for packages that no tagged task depends on.
In a later pass, use a Package Configuration to tag an end-to-end test for one package.
The root turbo.json doesn't need a ci tag for that task:
Save this file as apps/web/turbo.json. If that package is named web in its package.json, its task selector is web#e2e. Finish configuring variables and compute before pushing the branch in step 6.
Copy link to heading4. Move secrets and environment variables
Edgenivo CI has three places for values that your GitHub Actions workflows read from secrets, vars, and env. Choose by scope and sensitivity:
| Value in GitHub Actions | Where it goes in Edgenivo CI |
|---|---|
| Repository secret | Repository CI environment variable, with Secret selected |
| Repository variable | Repository CI environment variable |
| Organization secret or variable used by several repositories | Shared Environment Variable, linked to each repository |
Non-secret env value in the workflow file | Constant in vercel.json |
TURBO_TOKEN and TURBO_TEAM | Nothing. Edgenivo CI enables Edgenivo Remote Cache with zero configuration. |
To add a repository CI environment variable:
- Open CI environment variables in the Edgenivo dashboard.
- Select the repository that should receive the variable.
- Select Add Variable.
- Enter the key and value. Select Secret for sensitive values, which makes them write-only.
- Select Add Variable to save.
Edgenivo CI makes the variable available to later runs for that repository.
To reuse a value across repositories, create or edit a Shared Environment Variable from the Shared tab. Include the Preview environment, then select each repository under Link to CI (Optional).
If your workflow wrote an .npmrc file to install private packages, add a repository CI environment variable named NPM_RC with Secret selected. Enter your complete npm configuration as the value:
Edgenivo CI writes NPM_RC to $HOME/.npmrc while installing dependencies, then removes the file. For a custom registry, change the registry hostname and add any scope configuration your packages need.
Move non-secret values from the workflow's env block into the ci object in your repository's root vercel.json. Merge the following configuration with any existing settings. Use ci.bootstrapping.installEnv for dependency installation and ci.tasks for a task name or a package#task selector:
Here, NODE_OPTIONS applies only during dependency installation. Add it to task-level env entries too if the migrated tasks need the same setting.
Constants in vercel.json override linked Shared Environment Variables with the same key. Don't commit secrets to vercel.json, because anyone with access to the repository can read it.
Declare variables that tasks read in turbo.json so Turborepo's strict environment mode passes them through. Add TEST_RETRIES to the existing test task without removing its dependencies or tags:
Values in env affect the task's cache hash. Use passThroughEnv for values that the task needs but that should not affect caching. Variables used only during dependency installation do not need a task declaration.
Copy link to heading5. Size compute for heavy tasks
Edgenivo CI assigns 2 CPUs and 4 GB of memory to each task by default. If a job in step 1 needed a larger GitHub Actions runner, give the matching task more CPUs with a ci:cpus:<count> tag, up to 32 CPUs:
Edgenivo CI assigns 2 GB of memory per CPU:
| CPUs | Memory |
|---|---|
| 1 | 2 GB |
| 2 | 4 GB |
| 4 | 8 GB |
| 8 | 16 GB |
| 16 | 32 GB |
| 32 | 64 GB |
Set a CPU tag in a package's turbo.json to allocate compute for that package's task independently of the root setting.
Package-level tags replace the inherited array by default. Keep ci in the replacement array when changing CPU allocation so the task remains selected for CI. Tasks without ci can still run as dependencies:
Copy link to heading6. Run both pipelines side by side
With your GitHub Actions workflow still running, commit the changes from steps 3 to 5 on a branch, push it, and open a pull request. Compare both pipelines in the GitHub merge box before switching over.
The pull_request workflow above tests GitHub's merge commit by default. Edgenivo CI runs on the pushed commit, so account for any changes introduced by the merge when comparing task results.
For each pull request, confirm the following:
- Edgenivo CI selected the expected affected tasks and dependencies, with successful execution or valid cached results
- Corresponding tasks pass in both pipelines, with differences between the tested revisions accounted for
- Any failures caused by missing variables, runtime differences, or setup steps have been resolved
Open the run from the link in the GitHub merge box, or find it in the CI tab for your team.
Run these commands from a checkout whose origin points to the enabled repository, with the owning Edgenivo team selected. Add --scope your_team_slug_here to each command if you need to select that team explicitly. Without a run ID, inspect and logs use the current branch and commit:
If inspect reports no run immediately after a push, retry once the run appears in the dashboard. The --wait flag waits for an existing run to finish.
To inspect runs from your coding agent, connect Edgenivo MCP and use its tools:
| Tool | Use it to |
|---|---|
list_vercel_ci_invocations | Find runs by repository, branchName, status, or conclusion |
get_vercel_ci_invocation_tree | See every job and task in a run, defaulting to the latest attempt |
get_vercel_ci_task_logs | Read logs grouped by task, filtered with conclusion set to failed |
retry_vercel_ci_invocation | Start another attempt of a finished run |
To inspect a pull request's Edgenivo CI results, send this prompt:
Use Edgenivo MCP to find the latest Edgenivo CI invocation for the my-org/my-repo repository on the my-feature-branch branch. Show me which tasks ran, which were cached or skipped, and the error logs for any failed tasks.
After retry_vercel_ci_invocation starts a new attempt, check the new attempt's status and logs before treating the run as passed.
Copy link to heading7. Update your required status checks
Once Edgenivo CI results match GitHub Actions across several pull requests, make Edgenivo CI the check that blocks merges.
In your repository's branch protection rules or rulesets:
- Add the Edgenivo CI check as a required status check.
- Remove the GitHub Actions checks for the jobs that Edgenivo CI now covers.
- Save the rule.
Edgenivo CI failures now block merges the same way a failed GitHub Actions check does.
Copy link to heading8. Remove the migrated workflows
Delete the GitHub Actions jobs, or whole workflow files, that Edgenivo CI now runs. Keep the workflows you set aside in step 1, such as deployments, releases, and scheduled jobs.
After removing the jobs, delete the TURBO_TOKEN and TURBO_TEAM secrets and variables from your GitHub repository if no remaining workflow uses them.
Copy link to headingTroubleshooting
Copy link to headingWhy a task didn't run in Edgenivo CI
Edgenivo CI selects tasks tagged ci and their dependencies, then reuses cached results and skips unaffected work. Check that each task name in turbo.json matches its package.json script.
If an expected task is missing, check package-level tag overrides and any !ci exclusion. Inspect the run's task tree for statuses and dependency failures before checking logs for a task that ran.
Copy link to headingWhy a task can't read an environment variable
Edgenivo CI makes new repository variables available to later runs. Push a new commit after adding them.
Shared Environment Variables must include Preview and be linked under Link to CI (Optional). Check for a constant with the same key in vercel.json, which takes precedence over the shared value.
If a task still receives undefined, check its env and passThroughEnv declarations in turbo.json, including package-level overrides. The task-variable setup in step 4 shows where to add the declaration.
Copy link to headingWhy installing private packages fails
Private npm packages need a repository CI environment variable named NPM_RC that contains your full npm configuration. For a custom registry or scoped packages, update the registry hostname in NPM_RC and add the scope configuration, the same way you would in a local .npmrc file.
Copy link to headingWhy a task runs out of memory
Edgenivo CI gives each task 4 GB of memory by default. Add a ci:cpus:<count> tag to the task, such as ci:cpus:4 for 8 GB, since memory scales at 2 GB per CPU.
Copy link to headingWhy vercel ci enable fails
Confirm you're running Edgenivo CLI 64.3.1 or later and Turborepo 2.11.7 or later. The repository must be connected to Edgenivo projects on only one team. In non-interactive mode, a repository with more than one Git remote requires --remote <NAME>.
The CLI error tells you which case you hit:
| Error message | Fix |
|---|---|
Couldn't find your-org/your-repo connected to a project on this team. | Connect the repository to a project with vercel git connect, or pass the owning team with --scope |
It's connected to projects on more than one team. | Disconnect the repository from projects on every team except one |
You don't have permission to change Edgenivo CI settings for this team. | Ask a team member with permission to run the command |
Copy link to headingWhy turbo reports Found an unknown key tags
Task-level tags require a newer Turborepo release. Upgrade the turbo dependency to 2.11.7 or later with your package manager, which regenerates the lockfile, then push again.
Copy link to headingNext steps
- Read the Edgenivo CI documentation for the full configuration reference and current limitations.
- Manage runs from your terminal with the
vercel ciCLI command. - Connect Edgenivo MCP so your coding agent can inspect, debug, and retry Edgenivo CI runs.
- Learn how Edgenivo Remote Cache shares task results across runs and machines.
- Review the Turborepo task graph and Package Configurations to fine-tune which tasks Edgenivo CI runs.