I am using GitHub Apps in order to integrate GitHub in our product.
Looks like I need to have the app installed (not only request a token) in order to list user’s private repos.
So what I am doing is opening a pop up with the installation of the app, using this link https://github.com/apps/APP-NAME/installations/new
This works fine for the first time, the app gets installed and I receive the code to exchange for the token.
The problem is when the user already has the app installed, I would expect this new installation dialog to skip the installation setup(since the user already did that) and instead give me the access token and close the pop up.
Do I have any way to achieve that? Maybe specifying some kind of parameter?
If not, can I use git hub apps in some way that allows me to retrieve the private repos without having to install it (AFAIK the legacy Oath apps allow you to do that by specifying scopes)?
Once you install GitHub App into a user’s account, you need to obtain installation ID. This ID does not change.
In order to get private repos in the account you need to send GutHub API request with an installation access token. To obtain it you need to perform two steps
- Sign GitHub App JWT with the private key of the app – see here
- Exchange JWT for an installation access token – see here
Here is a sample workflow to do this:
name: Get GitHub App Installation Access Token and List Repositories
on:
push:
branches:
- main
jobs:
get-installation-token:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Generate GitHub App JWT
id: generate_jwt
uses: tibdex/github-app-token@v1
with:
app_id: ${{ secrets.GITHUB_APP_ID }}
private_key: ${{ secrets.GITHUB_PRIVATE_KEY }}
- name: Get GitHub App Installation Access Token
id: get_installation_token
uses: actions/github-script@v6
with:
script: |
const jwt = `{{ steps.generate_jwt.outputs.token }}`;
const octokit = new github.getOctokit(jwt);
const { data: installations } = await octokit.request('GET /app/installations');
const installation_id = installations[0].id;
const { data: tokenData } = await octokit.request('POST /app/installations/{installation_id}/access_tokens', {
installation_id
});
return tokenData.token;
- name: List Repositories Accessible by GitHub App
uses: actions/github-script@v6
with:
script: |
const token = `{{ steps.get_installation_token.outputs.result }}`;
const octokit = new github.getOctokit(token);
const { data: repos } = await octokit.request('GET /users/{user-name}/repos');
console.log('Repositories accessible by the GitHub App installation:', repos);
- name: Display Repositories
run: |
echo "Repositories: ${{ steps.list_repos.outputs.repos }}"