tests; update README
This commit is contained in:
@@ -195,6 +195,28 @@ jobs:
|
||||
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
|
||||
|
||||
> [!NOTE]
|
||||
@@ -335,6 +357,13 @@ steps:
|
||||
> [!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.
|
||||
|
||||
### `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>`
|
||||
|
||||
**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␊
|
||||
{"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
|
||||
|
||||
> stderr
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user