tests; update README
This commit is contained in:
@@ -195,6 +195,28 @@ jobs:
|
|||||||
body: "Hello, World!"
|
body: "Hello, World!"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Create a token for an enterprise installation
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
on: [workflow_dispatch]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
hello-world:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/create-github-app-token@v2
|
||||||
|
id: app-token
|
||||||
|
with:
|
||||||
|
app-id: ${{ vars.APP_ID }}
|
||||||
|
private-key: ${{ secrets.PRIVATE_KEY }}
|
||||||
|
enterprise: my-enterprise-slug
|
||||||
|
- name: Call enterprise management REST API with gh
|
||||||
|
run: |
|
||||||
|
gh api /enterprises/my-enterprise-slug/apps/installable_organizations
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||||
|
```
|
||||||
|
|
||||||
### Create a token with specific permissions
|
### Create a token with specific permissions
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
@@ -335,6 +357,13 @@ steps:
|
|||||||
> [!NOTE]
|
> [!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.
|
> 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.
|
||||||
|
|
||||||
|
### `enterprise`
|
||||||
|
|
||||||
|
**Optional:** The slug of the enterprise to generate a token for enterprise-level app installations.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> The `enterprise` input is mutually exclusive with `owner` and `repositories`. GitHub Apps can be installed on enterprise accounts with permissions that let them call enterprise management APIs. Enterprise installations do not grant access to organization or repository resources.
|
||||||
|
|
||||||
### `permission-<permission name>`
|
### `permission-<permission name>`
|
||||||
|
|
||||||
**Optional:** The permissions to grant to the token. By default, the token inherits all of the installation's permissions. We recommend to explicitly list the permissions that are required for a use case. This follows GitHub's own recommendation to [control permissions of `GITHUB_TOKEN` in workflows](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token). The documentation also lists all available permissions, just prefix the permission key with `permission-` (e.g., `pull-requests` → `permission-pull-requests`).
|
**Optional:** The permissions to grant to the token. By default, the token inherits all of the installation's permissions. We recommend to explicitly list the permissions that are required for a use case. This follows GitHub's own recommendation to [control permissions of `GITHUB_TOKEN` in workflows](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token). The documentation also lists all available permissions, just prefix the permission key with `permission-` (e.g., `pull-requests` → `permission-pull-requests`).
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { test } from "./main.js";
|
||||||
|
delete process.env.INPUT_OWNER;
|
||||||
|
delete process.env.INPUT_REPOSITORIES;
|
||||||
|
|
||||||
|
// Verify `main` handles when no enterprise installation is found.
|
||||||
|
await test((mockPool) => {
|
||||||
|
process.env.INPUT_ENTERPRISE = "test-enterprise";
|
||||||
|
|
||||||
|
|
||||||
|
// Mock the /app/installations endpoint to return only non-enterprise installations
|
||||||
|
mockPool
|
||||||
|
.intercept({
|
||||||
|
path: "/app/installations",
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
accept: "application/vnd.github.v3+json",
|
||||||
|
"user-agent": "actions/create-github-app-token",
|
||||||
|
// Intentionally omitting the `authorization` header, since JWT creation is not idempotent.
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.reply(
|
||||||
|
200,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
id: "111111",
|
||||||
|
app_slug: "github-actions",
|
||||||
|
target_type: "Organization",
|
||||||
|
account: { login: "some-org" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "222222",
|
||||||
|
app_slug: "github-actions",
|
||||||
|
target_type: "User",
|
||||||
|
account: { login: "some-user" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{ headers: { "content-type": "application/json" } }
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { DEFAULT_ENV } from "./main.js";
|
||||||
|
|
||||||
|
// Verify `main` exits with an error when `enterprise` is used with both `owner` and `repositories` inputs.
|
||||||
|
try {
|
||||||
|
// Set up environment with enterprise, owner, and repositories all set
|
||||||
|
for (const [key, value] of Object.entries(DEFAULT_ENV)) {
|
||||||
|
process.env[key] = value;
|
||||||
|
}
|
||||||
|
process.env.INPUT_ENTERPRISE = "test-enterprise";
|
||||||
|
process.env.INPUT_OWNER = "test-owner";
|
||||||
|
process.env.INPUT_REPOSITORIES = "repo1,repo2";
|
||||||
|
|
||||||
|
await import("../main.js");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error.message);
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { DEFAULT_ENV } from "./main.js";
|
||||||
|
|
||||||
|
// Verify `main` exits with an error when `enterprise` is used with `owner` input.
|
||||||
|
try {
|
||||||
|
// Set up environment with enterprise and owner both set
|
||||||
|
for (const [key, value] of Object.entries(DEFAULT_ENV)) {
|
||||||
|
process.env[key] = value;
|
||||||
|
}
|
||||||
|
process.env.INPUT_ENTERPRISE = "test-enterprise";
|
||||||
|
process.env.INPUT_OWNER = "test-owner";
|
||||||
|
|
||||||
|
await import("../main.js");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error.message);
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { DEFAULT_ENV } from "./main.js";
|
||||||
|
|
||||||
|
// Verify `main` exits with an error when `enterprise` is used with `repositories` input.
|
||||||
|
try {
|
||||||
|
// Set up environment with enterprise and repositories both set
|
||||||
|
for (const [key, value] of Object.entries(DEFAULT_ENV)) {
|
||||||
|
process.env[key] = value;
|
||||||
|
}
|
||||||
|
process.env.INPUT_ENTERPRISE = "test-enterprise";
|
||||||
|
process.env.INPUT_REPOSITORIES = "repo1,repo2";
|
||||||
|
|
||||||
|
await import("../main.js");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error.message);
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import { test } from "./main.js";
|
||||||
|
|
||||||
|
// Verify `main` successfully obtains a token when only the `enterprise` input is set.
|
||||||
|
await test((mockPool) => {
|
||||||
|
process.env.INPUT_ENTERPRISE = "test-enterprise";
|
||||||
|
delete process.env.INPUT_OWNER;
|
||||||
|
delete process.env.INPUT_REPOSITORIES;
|
||||||
|
|
||||||
|
// Mock the /app/installations endpoint to return an enterprise installation
|
||||||
|
const mockInstallationId = "123456";
|
||||||
|
const mockAppSlug = "github-actions";
|
||||||
|
mockPool
|
||||||
|
.intercept({
|
||||||
|
path: "/app/installations",
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
accept: "application/vnd.github.v3+json",
|
||||||
|
"user-agent": "actions/create-github-app-token",
|
||||||
|
// Intentionally omitting the `authorization` header, since JWT creation is not idempotent.
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.reply(
|
||||||
|
200,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
id: mockInstallationId,
|
||||||
|
app_slug: mockAppSlug,
|
||||||
|
target_type: "Enterprise",
|
||||||
|
account: { login: "test-enterprise" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{ headers: { "content-type": "application/json" } }
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import { test } from "./main.js";
|
||||||
|
|
||||||
|
// Verify `main` successfully generates enterprise token with basic functionality.
|
||||||
|
await test((mockPool) => {
|
||||||
|
process.env.INPUT_ENTERPRISE = "test-enterprise";
|
||||||
|
delete process.env.INPUT_OWNER;
|
||||||
|
delete process.env.INPUT_REPOSITORIES;
|
||||||
|
|
||||||
|
// Mock the /app/installations endpoint to return an enterprise installation
|
||||||
|
const mockInstallationId = "123456";
|
||||||
|
const mockAppSlug = "github-actions";
|
||||||
|
mockPool
|
||||||
|
.intercept({
|
||||||
|
path: "/app/installations",
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
accept: "application/vnd.github.v3+json",
|
||||||
|
"user-agent": "actions/create-github-app-token",
|
||||||
|
// Intentionally omitting the `authorization` header, since JWT creation is not idempotent.
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.reply(
|
||||||
|
200,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
id: mockInstallationId,
|
||||||
|
app_slug: mockAppSlug,
|
||||||
|
target_type: "Enterprise",
|
||||||
|
account: { login: "test-enterprise" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{ headers: { "content-type": "application/json" } }
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { test } from "./main.js";
|
||||||
|
|
||||||
|
// Verify `main` successfully generates enterprise token with specific permissions.
|
||||||
|
await test((mockPool) => {
|
||||||
|
process.env.INPUT_ENTERPRISE = "test-enterprise";
|
||||||
|
delete process.env.INPUT_OWNER;
|
||||||
|
delete process.env.INPUT_REPOSITORIES;
|
||||||
|
process.env["INPUT_PERMISSION-ENTERPRISE-ORGANIZATIONS"] = "read";
|
||||||
|
process.env["INPUT_PERMISSION-ENTERPRISE-PEOPLE"] = "write";
|
||||||
|
|
||||||
|
// Mock the /app/installations endpoint to return an enterprise installation
|
||||||
|
const mockInstallationId = "123456";
|
||||||
|
const mockAppSlug = "github-actions";
|
||||||
|
mockPool
|
||||||
|
.intercept({
|
||||||
|
path: "/app/installations",
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
accept: "application/vnd.github.v3+json",
|
||||||
|
"user-agent": "actions/create-github-app-token",
|
||||||
|
// Intentionally omitting the `authorization` header, since JWT creation is not idempotent.
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.reply(
|
||||||
|
200,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
id: mockInstallationId,
|
||||||
|
app_slug: mockAppSlug,
|
||||||
|
target_type: "Enterprise",
|
||||||
|
account: { login: "test-enterprise" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{ headers: { "content-type": "application/json" } }
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -39,6 +39,99 @@ Generated by [AVA](https://avajs.dev).
|
|||||||
POST /api/v3/app/installations/123456/access_tokens␊
|
POST /api/v3/app/installations/123456/access_tokens␊
|
||||||
{"repositories":["create-github-app-token"]}`
|
{"repositories":["create-github-app-token"]}`
|
||||||
|
|
||||||
|
## main-enterprise-only-success.test.js
|
||||||
|
|
||||||
|
> stderr
|
||||||
|
|
||||||
|
''
|
||||||
|
|
||||||
|
> stdout
|
||||||
|
|
||||||
|
`Creating enterprise installation token for enterprise "test-enterprise".␊
|
||||||
|
### Found enterprise installation: {␊
|
||||||
|
"id": "123456",␊
|
||||||
|
"app_slug": "github-actions",␊
|
||||||
|
"target_type": "Enterprise",␊
|
||||||
|
"account": {␊
|
||||||
|
"login": "test-enterprise"␊
|
||||||
|
}␊
|
||||||
|
}␊
|
||||||
|
::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 /app/installations␊
|
||||||
|
POST /app/installations/123456/access_tokens␊
|
||||||
|
null`
|
||||||
|
|
||||||
|
## main-enterprise-token-success.test.js
|
||||||
|
|
||||||
|
> stderr
|
||||||
|
|
||||||
|
''
|
||||||
|
|
||||||
|
> stdout
|
||||||
|
|
||||||
|
`Creating enterprise installation token for enterprise "test-enterprise".␊
|
||||||
|
### Found enterprise installation: {␊
|
||||||
|
"id": "123456",␊
|
||||||
|
"app_slug": "github-actions",␊
|
||||||
|
"target_type": "Enterprise",␊
|
||||||
|
"account": {␊
|
||||||
|
"login": "test-enterprise"␊
|
||||||
|
}␊
|
||||||
|
}␊
|
||||||
|
::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 /app/installations␊
|
||||||
|
POST /app/installations/123456/access_tokens␊
|
||||||
|
null`
|
||||||
|
|
||||||
|
## main-enterprise-token-with-permissions.test.js
|
||||||
|
|
||||||
|
> stderr
|
||||||
|
|
||||||
|
''
|
||||||
|
|
||||||
|
> stdout
|
||||||
|
|
||||||
|
`Creating enterprise installation token for enterprise "test-enterprise".␊
|
||||||
|
### Found enterprise installation: {␊
|
||||||
|
"id": "123456",␊
|
||||||
|
"app_slug": "github-actions",␊
|
||||||
|
"target_type": "Enterprise",␊
|
||||||
|
"account": {␊
|
||||||
|
"login": "test-enterprise"␊
|
||||||
|
}␊
|
||||||
|
}␊
|
||||||
|
::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 /app/installations␊
|
||||||
|
POST /app/installations/123456/access_tokens␊
|
||||||
|
{"permissions":{"enterprise_organizations":"read","enterprise_people":"write"}}`
|
||||||
|
|
||||||
## main-missing-owner.test.js
|
## main-missing-owner.test.js
|
||||||
|
|
||||||
> stderr
|
> stderr
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user