#350

GitHub: Actions variables for repositories and organizations (feature request)

Openwaynesun09opened 6d ago

Problem

The GitHub emulator implements Actions secrets, but not Actions variables. Tools that configure a repository often write both. Code that reads configuration from variables, such as an allowlist stored in an organization variable, receives 404 from the emulator. Verified on main at b75beb7 with npx emulate@0.13.0.

Reproduction

Seed octocat/hello-world, an organization my-org with octocat as an admin member, a repository my-org/org-repo, and a repro_token for octocat. Start the GitHub service:

npx emulate@0.13.0 start --service github --port 4001 --seed emulate.config.yaml
curl -s -i -X POST http://localhost:4001/repos/octocat/hello-world/actions/variables \
  -H 'Authorization: Bearer repro_token' -H 'Content-Type: application/json' \
  -d '{"name":"MY_VAR","value":"one"}'
curl -s -i http://localhost:4001/repos/octocat/hello-world/actions/variables -H 'Authorization: Bearer repro_token'
curl -s -i http://localhost:4001/orgs/my-org/actions/variables -H 'Authorization: Bearer repro_token'
curl -s -i http://localhost:4001/repos/my-org/org-repo/actions/organization-variables -H 'Authorization: Bearer repro_token'

Each request returns:

HTTP/1.1 404 Not Found
{"message":"Not Found","documentation_url":"https://emulate.dev/github"}

Secrets endpoints on the same repository succeed. The failure is specific to variables.

GitHub behavior

Repository variables:

Method and pathResult
GET /repos/{owner}/{repo}/actions/variables200 with { total_count, variables: [{ name, value, created_at, updated_at }] }, paginated with per_page (max 30) and page
POST /repos/{owner}/{repo}/actions/variables201
GET /repos/{owner}/{repo}/actions/variables/{name}200 with the variable, 404 if absent
PATCH /repos/{owner}/{repo}/actions/variables/{name}204; accepts name (rename) and value
DELETE /repos/{owner}/{repo}/actions/variables/{name}204
GET /repos/{owner}/{repo}/actions/organization-variables200 with the organization variables this repository can use

Organization variables use the corresponding paths under /orgs/{org}/actions/variables. Payloads accept visibility (all, private, or selected) and selected_repository_ids. Organization variables also provide selection endpoints: GET and PUT /orgs/{org}/actions/variables/{name}/repositories, and PUT and DELETE /orgs/{org}/actions/variables/{name}/repositories/{repository_id}. The selection endpoints return 409 when variable visibility is not selected. Organization variable responses include visibility and selected_repositories_url.

Unlike secrets, the API returns variable values in plain text.

Access requirements: the API requires collaborator access to the repository. Personal access tokens (classic) require the repo scope for repository variables and admin:org for organization variables. GitHub App installation tokens require the actions_variables permission for repository variables and organization_actions_variables for organization variables.

Docs: https://docs.github.com/en/rest/actions/variables

Proposed scope

  • Repository variables: list, create, get, update, and delete. Return 404 on a missing name for GET or PATCH, which clients use to decide between update and create.
  • Organization variables: the same operations, plus visibility, selected_repository_ids, and the selected repository endpoints.
  • GET /repos/{owner}/{repo}/actions/organization-variables, filtered by visibility and repository selection.
  • GitHub App permission checks for actions_variables and organization_actions_variables, matching existing installation token checks for secrets.
  • Optional: seed variables from the configuration file under a repository or organization.
  • Out of scope for the initial implementation: environment variables (/repos/{owner}/{repo}/environments/{environment_name}/variables).

Proposed implementation

The secrets routes in actions.ts already model this repository and organization split. They use a GitHubSecret entity carrying repo_id, org_id, name, and visibility, with GitHub App permission checks via assertRepoPermission(..., "secrets"):

https://github.com/vercel-labs/emulate/blob/b75beb7ce7d78676d471fff47432b77be6ff6528/packages/@emulators/github/src/routes/actions.ts#L658-L791

https://github.com/vercel-labs/emulate/blob/b75beb7ce7d78676d471fff47432b77be6ff6528/packages/@emulators/github/src/entities.ts#L430-L435

Variables can follow the same pattern: introduce a GitHubVariable entity that also stores value, and verify the actions_variables permission key instead of secrets.

Activity

0

No activity yet.