Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04
11 changes: 11 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "Ona",
"build": {
"context": ".",
"dockerfile": "Dockerfile"
},
"features": {
"ghcr.io/devcontainers/features/node:1": {}
}
}

55 changes: 55 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: CI

on:
push:
branches:
- main
pull_request:

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install dependencies
run: npm ci

- name: Run tests
run: npm test

check-dist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install dependencies
run: npm ci

- name: Build distribution
run: npm run build

- name: Compare distributions
run: |
if [ "$(git diff --ignore-space-at-eol --text dist/ | wc -l)" -gt "0" ]; then
echo "::error::Detected uncommitted changes after build. Run 'npm run build' and commit the changes."
git diff --text dist/
exit 1
fi

- name: Verify action.yml points to dist
run: |
if ! grep -q "main: 'dist/index.mjs'" action.yml; then
echo "::error::action.yml must point to dist/index.mjs"
exit 1
fi
39 changes: 39 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Release

on:
push:
tags:
- 'v*'

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install dependencies
run: npm ci

- name: Build distribution
run: npm run build

- name: Commit dist if changed
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add dist/
git diff --staged --quiet || git commit -m "Build dist for release ${{ github.ref_name }}"
git push origin HEAD:main

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
draft: false
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules/
*.log
.DS_Store
.env
.env.local
*.pem
98 changes: 56 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,62 +1,76 @@
# GitHub Application Auth Action

This action is used to obtain a short-lived access token, to perform actions on behalf of an installed github app.
Generate short-lived access tokens for GitHub App authentication. Use this to perform cross-repository operations, trigger workflows, or create pull requests with fine-grained permissions instead of using personal access tokens.

A typical use case for this is to use the app instead of a PAT, which is short-lived, in order to perform cross-repository operations. Or any other ones that are not possible by using the repository scoped `GITHUB_TOKEN`.
## Setup

You need a GitHub App with a private key. See [GitHub's documentation](https://docs.github.com/en/apps/creating-github-apps) for creating and installing a GitHub App.

Store three values as repository secrets:
- `APP_ID` - Your GitHub App ID
- `INSTALLATION_ID` - The installation ID for your org/repo
- `APP_PRIVATE_KEY` - The entire `.pem` file contents (including BEGIN/END lines)

**Security**: Never commit your private key to version control.

## Inputs

### `private-key`
| Input | Required | Description |
|-------|----------|-------------|
| `app-id` | Yes | The ID of your GitHub App (found in app settings) |
| `installation-id` | Yes | The [installation ID](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app-installation) for your organization/repository |
| `private-key` | Yes | The app's [private key](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps) (store as a secret) |

**Required** The app' [private key](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps).
## Outputs

### `app-id`
| Output | Description |
|--------|-------------|
| `token` | A short-lived [installation access token](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-an-installation-access-token-for-a-github-app) (typically valid for 1 hour) |

**Required** The ID of the [app](https://docs.github.com/en/apps/creating-github-apps/creating-github-apps/creating-a-github-app).
## Usage

### `installation-id`
```yaml
- name: Generate token
id: app-auth
uses: gitpod-io/gh-app-auth@v0.2
with:
app-id: ${{ secrets.APP_ID }}
installation-id: ${{ secrets.INSTALLATION_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}

**Required** The application's [installation ID](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app-installation).
- name: Create pull request
uses: peter-evans/create-pull-request@v6
with:
token: ${{ steps.app-auth.outputs.token }}
```

## Outputs
The token is automatically masked in logs for security.

### `token`
## Finding Your IDs

The short-lived [installation access token](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-an-installation-access-token-for-a-github-app).
- **App ID**: Found at the top of your GitHub App settings page
- **Installation ID**: In the URL when you configure your app installation
- `https://github.com/settings/installations/12345678` ← this number
- Or via CLI: `gh api /orgs/<org-name>/installation | jq .id`

## Example usage
## Development

### Building

```yaml
uses: gitpod-io/gh-app-auth@v0.1
with:
app-id: '1234'
installation-id: '1234556678'
private-key: ${{ secrets.private-key }}
```bash
npm install
npm run build
```

#### Triggering an action in another repository
This bundles the code and dependencies into `dist/index.mjs` for distribution.

```yaml
- uses: gitpod-io/gh-app-auth@v0.1
id: gh-auth
with:
app-id: '1234'
installation-id: '1234556678'
private-key: ${{ secrets.private-key }}
- name: Test
uses: actions/github-script@v6
with:
github-token: ${{ steps.gh-auth.outputs.token }}
script: |
const result = await github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: 'your-repository',
workflow_id: 'triggerd-action.yaml',
ref: 'main',
inputs: {
"your": 'input',
}
})
console.log(result)
```
### Releasing

1. Update version in `package.json`
2. Commit changes: `git commit -am "Bump version to x.y.z"`
3. Create and push a tag: `git tag vx.y.z && git push origin vx.y.z`
4. The GitHub Action will automatically create a release

## License

ISC
9 changes: 6 additions & 3 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: 'Application Auth'
description: ''
description: 'Generate short-lived access tokens for GitHub App authentication'
inputs:
private-key:
description: 'private key of the app'
Expand All @@ -15,5 +15,8 @@ outputs:
token:
description: 'the short-lived token used for authentication'
runs:
using: 'node16'
main: 'index.mjs'
using: 'node20'
main: 'dist/index.mjs'
branding:
icon: 'lock'
color: 'blue'
Loading