From 7890ff190ee15b86d67fdf272abab9691f524f5a Mon Sep 17 00:00:00 2001 From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com> Date: Fri, 8 May 2026 17:10:38 -0700 Subject: [PATCH 1/7] Support full repository names Allow repositories entries to include an owner when it matches the resolved owner. This supports values like github.repository while preserving the existing owner/default-owner behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- README.md | 10 ++- action.yml | 2 +- lib/main.js | 50 +++++++++-- tests/index.js.snapshot | 87 +++++++++++++++++++ ...token-get-owner-set-repo-full-name.test.js | 8 ++ ...-get-owner-set-repo-invalid-format.test.js | 13 +++ ...-get-owner-set-repo-owner-mismatch.test.js | 13 +++ ...wner-unset-repo-full-name-and-bare.test.js | 8 ++ ...et-owner-unset-repo-owner-mismatch.test.js | 13 +++ 9 files changed, 196 insertions(+), 8 deletions(-) create mode 100644 tests/main-token-get-owner-set-repo-full-name.test.js create mode 100644 tests/main-token-get-owner-set-repo-invalid-format.test.js create mode 100644 tests/main-token-get-owner-set-repo-owner-mismatch.test.js create mode 100644 tests/main-token-get-owner-unset-repo-full-name-and-bare.test.js create mode 100644 tests/main-token-get-owner-unset-repo-owner-mismatch.test.js diff --git a/README.md b/README.md index 4325716..4266c6e 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,12 @@ jobs: body: "Hello, World!" ``` +The `repositories` input accepts comma or newline-separated repository names. It also accepts full repository names, which is useful when passing `${{ github.repository }}`: + +```yaml +repositories: ${{ github.repository }},generic-submodule +``` + ### Create a token for all repositories in another owner's installation ```yaml @@ -373,10 +379,12 @@ steps: ### `repositories` -**Optional:** Comma or newline-separated list of repositories to grant access to. +**Optional:** Comma or newline-separated list of repositories to grant access to. Entries can be repository names, such as `repo1`, or full repository names, such as `owner/repo1`. > [!NOTE] > If `owner` is set and `repositories` is empty, access will be scoped to all repositories in the provided repository owner's installation. If `owner` and `repositories` are empty, access will be scoped to only the current repository. +> +> The owner portion of any full repository name in `repositories` must match the `owner` input, or the current repository owner if `owner` is unset. ### `enterprise` diff --git a/action.yml b/action.yml index a4e1148..8c8e43d 100644 --- a/action.yml +++ b/action.yml @@ -19,7 +19,7 @@ inputs: description: "The owner of the GitHub App installation (defaults to current repository owner)" required: false repositories: - description: "Comma or newline-separated list of repositories to install the GitHub App on (defaults to current repository if owner is unset)" + description: "Comma or newline-separated list of repository names or owner/repository names to install the GitHub App on (defaults to current repository if owner is unset)" required: false enterprise: description: "The slug of the enterprise account where the GitHub App is installed (cannot be used with 'owner' or 'repositories')" diff --git a/lib/main.js b/lib/main.js index 8fe0942..7108c3e 100644 --- a/lib/main.js +++ b/lib/main.js @@ -86,29 +86,67 @@ function resolveInstallationTarget(enterprise, owner, repositories, core) { return { type: "owner", owner }; } - const parsedOwner = owner || String(process.env.GITHUB_REPOSITORY_OWNER); + const target = normalizeRepositoryTarget(owner, repositories); if (!owner) { core.info( - `No 'owner' input provided. Using default owner '${parsedOwner}' to create token for the following repositories:${repositories - .map((repo) => `\n- ${parsedOwner}/${repo}`) + `No 'owner' input provided. Using default owner '${target.owner}' to create token for the following repositories:${target.repositories + .map((repo) => `\n- ${target.owner}/${repo}`) .join("")}` ); } else { core.info( - `Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:${repositories - .map((repo) => `\n- ${parsedOwner}/${repo}`) + `Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:${target.repositories + .map((repo) => `\n- ${target.owner}/${repo}`) .join("")}` ); } return { type: "repository", + owner: target.owner, + repositories: target.repositories, + }; +} + +function normalizeRepositoryTarget(owner, repositories) { + const parsedOwner = owner || String(process.env.GITHUB_REPOSITORY_OWNER); + const parsedRepositories = repositories.map(parseRepositoryInput); + + const mismatchedRepository = parsedRepositories.find( + (repository) => + repository.owner && + repository.owner.toLowerCase() !== parsedOwner.toLowerCase() + ); + + if (mismatchedRepository) { + throw new Error( + `Repository '${mismatchedRepository.input}' includes owner '${mismatchedRepository.owner}', which does not match the resolved owner '${parsedOwner}'.` + ); + } + + return { owner: parsedOwner, - repositories, + repositories: parsedRepositories.map((repository) => repository.name), }; } +function parseRepositoryInput(input) { + const parts = input.split("/"); + + if (parts.length === 1 && parts[0]) { + return { input, owner: "", name: parts[0] }; + } + + if (parts.length === 2 && parts[0] && parts[1]) { + return { input, owner: parts[0], name: parts[1] }; + } + + throw new Error( + `Invalid repository '${input}'. Expected 'repository' or 'owner/repository'.` + ); +} + function getTokenRetryDescription(target) { switch (target.type) { case "enterprise": diff --git a/tests/index.js.snapshot b/tests/index.js.snapshot index a77b6fa..a3dec31 100644 --- a/tests/index.js.snapshot +++ b/tests/index.js.snapshot @@ -296,6 +296,42 @@ POST /app/installations/123456/access_tokens {"repositories":["failed-repo"]} `; +exports[`main-token-get-owner-set-repo-full-name.test.js > stdout 1`] = ` +Inputs 'owner' and 'repositories' are set. Creating token for the following repositories: +- actions/create-github-app-token +::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a + +::set-output name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a + +::set-output name=installation-id::123456 + +::set-output name=app-slug::github-actions +::save-state name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a +::save-state name=expiresAt::2016-07-11T22:14:10Z +--- REQUESTS --- +GET /repos/actions/create-github-app-token/installation +POST /app/installations/123456/access_tokens +{"repositories":["create-github-app-token"]} +`; + +exports[`main-token-get-owner-set-repo-invalid-format.test.js > stderr 1`] = ` +Error: Invalid repository 'octocat/hello-world/extra'. Expected 'repository' or 'owner/repository'. + at parseRepositoryInput (file:///lib/main.js::) + at Array.map () + at normalizeRepositoryTarget (file:///lib/main.js::) + at resolveInstallationTarget (file:///lib/main.js::) + at main (file:///lib/main.js::) + at run (file:///main.js::) + at file:///main.js:: + at ModuleJob.run (node:internal/modules/esm/module_job::) + at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader::) + at async file:///tests/main-token-get-owner-set-repo-invalid-format.test.js:: +`; + +exports[`main-token-get-owner-set-repo-invalid-format.test.js > stdout 1`] = ` +::error::Invalid repository 'octocat/hello-world/extra'. Expected 'repository' or 'owner/repository'. +`; + exports[`main-token-get-owner-set-repo-network-error.test.js > stdout 1`] = ` Inputs 'owner' and 'repositories' are set. Creating token for the following repositories: - actions/network-repo @@ -316,6 +352,22 @@ POST /app/installations/123456/access_tokens {"repositories":["network-repo"]} `; +exports[`main-token-get-owner-set-repo-owner-mismatch.test.js > stderr 1`] = ` +Error: Repository 'octocat/hello-world' includes owner 'octocat', which does not match the resolved owner 'actions'. + at normalizeRepositoryTarget (file:///lib/main.js::) + at resolveInstallationTarget (file:///lib/main.js::) + at main (file:///lib/main.js::) + at run (file:///main.js::) + at file:///main.js:: + at ModuleJob.run (node:internal/modules/esm/module_job::) + at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader::) + at async file:///tests/main-token-get-owner-set-repo-owner-mismatch.test.js:: +`; + +exports[`main-token-get-owner-set-repo-owner-mismatch.test.js > stdout 1`] = ` +::error::Repository 'octocat/hello-world' includes owner 'octocat', which does not match the resolved owner 'actions'. +`; + exports[`main-token-get-owner-set-repo-set-to-many-newline.test.js > stdout 1`] = ` Inputs 'owner' and 'repositories' are set. Creating token for the following repositories: - actions/create-github-app-token @@ -391,6 +443,41 @@ POST /app/installations/123456/access_tokens null `; +exports[`main-token-get-owner-unset-repo-full-name-and-bare.test.js > stdout 1`] = ` +No 'owner' input provided. Using default owner 'actions' to create token for the following repositories: +- actions/create-github-app-token +- actions/toolkit +::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a + +::set-output name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a + +::set-output name=installation-id::123456 + +::set-output name=app-slug::github-actions +::save-state name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a +::save-state name=expiresAt::2016-07-11T22:14:10Z +--- REQUESTS --- +GET /repos/actions/create-github-app-token/installation +POST /app/installations/123456/access_tokens +{"repositories":["create-github-app-token","toolkit"]} +`; + +exports[`main-token-get-owner-unset-repo-owner-mismatch.test.js > stderr 1`] = ` +Error: Repository 'octocat/hello-world' includes owner 'octocat', which does not match the resolved owner 'actions'. + at normalizeRepositoryTarget (file:///lib/main.js::) + at resolveInstallationTarget (file:///lib/main.js::) + at main (file:///lib/main.js::) + at run (file:///main.js::) + at file:///main.js:: + at ModuleJob.run (node:internal/modules/esm/module_job::) + at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader::) + at async file:///tests/main-token-get-owner-unset-repo-owner-mismatch.test.js:: +`; + +exports[`main-token-get-owner-unset-repo-owner-mismatch.test.js > stdout 1`] = ` +::error::Repository 'octocat/hello-world' includes owner 'octocat', which does not match the resolved owner 'actions'. +`; + exports[`main-token-get-owner-unset-repo-set.test.js > stdout 1`] = ` No 'owner' input provided. Using default owner 'actions' to create token for the following repositories: - actions/create-github-app-token diff --git a/tests/main-token-get-owner-set-repo-full-name.test.js b/tests/main-token-get-owner-set-repo-full-name.test.js new file mode 100644 index 0000000..856a910 --- /dev/null +++ b/tests/main-token-get-owner-set-repo-full-name.test.js @@ -0,0 +1,8 @@ +import { test } from "./main.js"; + +// Verify `main` successfully obtains a token when the `owner` and `repositories` inputs are set, and `repositories` contains a full repository name. +await test(() => { + process.env.INPUT_OWNER = process.env.GITHUB_REPOSITORY_OWNER; + process.env.INPUT_REPOSITORIES = process.env.GITHUB_REPOSITORY; +}); + diff --git a/tests/main-token-get-owner-set-repo-invalid-format.test.js b/tests/main-token-get-owner-set-repo-invalid-format.test.js new file mode 100644 index 0000000..78014ed --- /dev/null +++ b/tests/main-token-get-owner-set-repo-invalid-format.test.js @@ -0,0 +1,13 @@ +import { DEFAULT_ENV } from "./main.js"; + +// Verify `main` exits with an error when a repository entry is neither a repository name nor an owner/repository name. +for (const [key, value] of Object.entries(DEFAULT_ENV)) { + process.env[key] = value; +} + +process.env.INPUT_OWNER = process.env.GITHUB_REPOSITORY_OWNER; +process.env.INPUT_REPOSITORIES = "octocat/hello-world/extra"; + +const { default: promise } = await import("../main.js"); +await promise; + diff --git a/tests/main-token-get-owner-set-repo-owner-mismatch.test.js b/tests/main-token-get-owner-set-repo-owner-mismatch.test.js new file mode 100644 index 0000000..2a7897b --- /dev/null +++ b/tests/main-token-get-owner-set-repo-owner-mismatch.test.js @@ -0,0 +1,13 @@ +import { DEFAULT_ENV } from "./main.js"; + +// Verify `main` exits with an error when a full repository name does not match the `owner` input. +for (const [key, value] of Object.entries(DEFAULT_ENV)) { + process.env[key] = value; +} + +process.env.INPUT_OWNER = process.env.GITHUB_REPOSITORY_OWNER; +process.env.INPUT_REPOSITORIES = "octocat/hello-world"; + +const { default: promise } = await import("../main.js"); +await promise; + diff --git a/tests/main-token-get-owner-unset-repo-full-name-and-bare.test.js b/tests/main-token-get-owner-unset-repo-full-name-and-bare.test.js new file mode 100644 index 0000000..5fff168 --- /dev/null +++ b/tests/main-token-get-owner-unset-repo-full-name-and-bare.test.js @@ -0,0 +1,8 @@ +import { test } from "./main.js"; + +// Verify `main` successfully obtains a token when `owner` is omitted and `repositories` mixes a full repository name with bare repository names. +await test(() => { + delete process.env.INPUT_OWNER; + process.env.INPUT_REPOSITORIES = `${process.env.GITHUB_REPOSITORY},toolkit`; +}); + diff --git a/tests/main-token-get-owner-unset-repo-owner-mismatch.test.js b/tests/main-token-get-owner-unset-repo-owner-mismatch.test.js new file mode 100644 index 0000000..b7ba367 --- /dev/null +++ b/tests/main-token-get-owner-unset-repo-owner-mismatch.test.js @@ -0,0 +1,13 @@ +import { DEFAULT_ENV } from "./main.js"; + +// Verify `main` exits with an error when a full repository name does not match the default owner. +for (const [key, value] of Object.entries(DEFAULT_ENV)) { + process.env[key] = value; +} + +delete process.env.INPUT_OWNER; +process.env.INPUT_REPOSITORIES = "octocat/hello-world"; + +const { default: promise } = await import("../main.js"); +await promise; + From 69ff067d88a37f06a4970d2ad1778f6ddc9ecd66 Mon Sep 17 00:00:00 2001 From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com> Date: Mon, 11 May 2026 11:01:40 -0700 Subject: [PATCH 2/7] Clarify repositories input description Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 8c8e43d..94223a2 100644 --- a/action.yml +++ b/action.yml @@ -19,7 +19,7 @@ inputs: description: "The owner of the GitHub App installation (defaults to current repository owner)" required: false repositories: - description: "Comma or newline-separated list of repository names or owner/repository names to install the GitHub App on (defaults to current repository if owner is unset)" + description: "Comma or newline-separated list of repository names or owner/repository names to grant the token access to (defaults to current repository if owner is unset)" required: false enterprise: description: "The slug of the enterprise account where the GitHub App is installed (cannot be used with 'owner' or 'repositories')" From 8a2937402f92de92ae05b10c2557abb86d4bb323 Mon Sep 17 00:00:00 2001 From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com> Date: Mon, 11 May 2026 11:03:33 -0700 Subject: [PATCH 3/7] Simplify repositories input wording Keep the action metadata description concise while documenting full owner/repository entries in the README note. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- README.md | 6 +++--- action.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4266c6e..aba3493 100644 --- a/README.md +++ b/README.md @@ -173,7 +173,7 @@ jobs: body: "Hello, World!" ``` -The `repositories` input accepts comma or newline-separated repository names. It also accepts full repository names, which is useful when passing `${{ github.repository }}`: +The `repositories` input also accepts entries with an owner, which is useful when passing `${{ github.repository }}`: ```yaml repositories: ${{ github.repository }},generic-submodule @@ -379,12 +379,12 @@ steps: ### `repositories` -**Optional:** Comma or newline-separated list of repositories to grant access to. Entries can be repository names, such as `repo1`, or full repository names, such as `owner/repo1`. +**Optional:** Comma or newline-separated list of repositories to grant access to. > [!NOTE] > If `owner` is set and `repositories` is empty, access will be scoped to all repositories in the provided repository owner's installation. If `owner` and `repositories` are empty, access will be scoped to only the current repository. > -> The owner portion of any full repository name in `repositories` must match the `owner` input, or the current repository owner if `owner` is unset. +> Repository entries may include an owner, for example `owner/repo1`. The owner portion must match the `owner` input, or the current repository owner if `owner` is unset. ### `enterprise` diff --git a/action.yml b/action.yml index 94223a2..9f45ab3 100644 --- a/action.yml +++ b/action.yml @@ -19,7 +19,7 @@ inputs: description: "The owner of the GitHub App installation (defaults to current repository owner)" required: false repositories: - description: "Comma or newline-separated list of repository names or owner/repository names to grant the token access to (defaults to current repository if owner is unset)" + description: "Comma or newline-separated list of repositories to grant the token access to (defaults to current repository if owner is unset)" required: false enterprise: description: "The slug of the enterprise account where the GitHub App is installed (cannot be used with 'owner' or 'repositories')" From af6e6ecf6148a832cfb4bb76051f3bf494ec3981 Mon Sep 17 00:00:00 2001 From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com> Date: Mon, 11 May 2026 11:28:58 -0700 Subject: [PATCH 4/7] Tighten repositories example Keep the README example concise and use a neutral repository name. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index aba3493..849dc84 100644 --- a/README.md +++ b/README.md @@ -173,10 +173,10 @@ jobs: body: "Hello, World!" ``` -The `repositories` input also accepts entries with an owner, which is useful when passing `${{ github.repository }}`: +You can include the current repository in the list with `${{ github.repository }}`: ```yaml -repositories: ${{ github.repository }},generic-submodule +repositories: ${{ github.repository }},repo2 ``` ### Create a token for all repositories in another owner's installation From 7989b94c942bb278c6545bffe7d1303865e3f301 Mon Sep 17 00:00:00 2001 From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com> Date: Mon, 11 May 2026 11:44:41 -0700 Subject: [PATCH 5/7] Cover non-current full repository names Add a regression test for owner/repository input where the first repository is not the current repository, and teach the test helper to mock the normalized installation lookup. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/index.js.snapshot | 19 +++++++++++++++++++ ...ner-set-repo-non-current-full-name.test.js | 12 ++++++++++++ tests/main.js | 7 ++++++- 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tests/main-token-get-owner-set-repo-non-current-full-name.test.js diff --git a/tests/index.js.snapshot b/tests/index.js.snapshot index a3dec31..1037218 100644 --- a/tests/index.js.snapshot +++ b/tests/index.js.snapshot @@ -352,6 +352,25 @@ POST /app/installations/123456/access_tokens {"repositories":["network-repo"]} `; +exports[`main-token-get-owner-set-repo-non-current-full-name.test.js > stdout 1`] = ` +Inputs 'owner' and 'repositories' are set. Creating token for the following repositories: +- actions/toolkit +- actions/checkout +::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a + +::set-output name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a + +::set-output name=installation-id::123456 + +::set-output name=app-slug::github-actions +::save-state name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a +::save-state name=expiresAt::2016-07-11T22:14:10Z +--- REQUESTS --- +GET /repos/actions/toolkit/installation +POST /app/installations/123456/access_tokens +{"repositories":["toolkit","checkout"]} +`; + exports[`main-token-get-owner-set-repo-owner-mismatch.test.js > stderr 1`] = ` Error: Repository 'octocat/hello-world' includes owner 'octocat', which does not match the resolved owner 'actions'. at normalizeRepositoryTarget (file:///lib/main.js::) diff --git a/tests/main-token-get-owner-set-repo-non-current-full-name.test.js b/tests/main-token-get-owner-set-repo-non-current-full-name.test.js new file mode 100644 index 0000000..d73c347 --- /dev/null +++ b/tests/main-token-get-owner-set-repo-non-current-full-name.test.js @@ -0,0 +1,12 @@ +import { DEFAULT_ENV, test } from "./main.js"; + +// Verify `main` normalizes full repository names before installation lookup and token scoping. +await test( + () => {}, + { + ...DEFAULT_ENV, + INPUT_OWNER: DEFAULT_ENV.GITHUB_REPOSITORY_OWNER, + INPUT_REPOSITORIES: `${DEFAULT_ENV.GITHUB_REPOSITORY_OWNER}/toolkit,checkout`, + }, +); + diff --git a/tests/main.js b/tests/main.js index 1edc643..3874dbc 100644 --- a/tests/main.js +++ b/tests/main.js @@ -60,8 +60,13 @@ export async function test(cb = (_mockPool) => {}, env = DEFAULT_ENV) { const mockAppSlug = "github-actions"; const owner = env.INPUT_OWNER ?? env.GITHUB_REPOSITORY_OWNER; const currentRepoName = env.GITHUB_REPOSITORY.split("/")[1]; + const firstRepositoryInput = + (env.INPUT_REPOSITORIES ?? currentRepoName) + .split(/[\n,]+/) + .map((repository) => repository.trim()) + .find(Boolean) ?? currentRepoName; const repo = encodeURIComponent( - (env.INPUT_REPOSITORIES ?? currentRepoName).split(",")[0] + firstRepositoryInput.split("/").pop() || firstRepositoryInput ); mockPool From 76ebc9694927cc84a361eaa58d19f99e46eb258b Mon Sep 17 00:00:00 2001 From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com> Date: Mon, 11 May 2026 12:07:35 -0700 Subject: [PATCH 6/7] Document repository input shapes Keep the action metadata concise while mentioning that repository entries can use either repo or owner/repo form. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 9f45ab3..f9cabcc 100644 --- a/action.yml +++ b/action.yml @@ -19,7 +19,7 @@ inputs: description: "The owner of the GitHub App installation (defaults to current repository owner)" required: false repositories: - description: "Comma or newline-separated list of repositories to grant the token access to (defaults to current repository if owner is unset)" + description: "Comma or newline-separated list of repositories to grant the token access to, such as 'repo' or 'owner/repo' (defaults to current repository if owner is unset)" required: false enterprise: description: "The slug of the enterprise account where the GitHub App is installed (cannot be used with 'owner' or 'repositories')" From daaf3b97abffc15feba91a57fcbcf31990925bdd Mon Sep 17 00:00:00 2001 From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com> Date: Mon, 11 May 2026 12:10:04 -0700 Subject: [PATCH 7/7] Keep repositories metadata concise Avoid implying that repository entries can target multiple owners from the compact action metadata description. The README keeps the detailed owner/repository guidance. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index f9cabcc..9f45ab3 100644 --- a/action.yml +++ b/action.yml @@ -19,7 +19,7 @@ inputs: description: "The owner of the GitHub App installation (defaults to current repository owner)" required: false repositories: - description: "Comma or newline-separated list of repositories to grant the token access to, such as 'repo' or 'owner/repo' (defaults to current repository if owner is unset)" + description: "Comma or newline-separated list of repositories to grant the token access to (defaults to current repository if owner is unset)" required: false enterprise: description: "The slug of the enterprise account where the GitHub App is installed (cannot be used with 'owner' or 'repositories')"