git - 如何在 pull 请求事件中获取 github 应用程序安装 ID?

标签 git github github-api github-app

我正在使用 Github 创建一个构建管道,它将在每个 pull 请求上创建一个检查运行以分析我的应用程序的性能。我已经创建 Github 应用程序并将其安装到我的存储库并生成了私钥。我需要执行 Authenticating as an installation 来获取访问 token 。

But as per the docs要获得安装的访问 token ,首先我必须获得该应用程序的安装列表,并且必须从该列表中找到特定的安装。但是我不知道如何为在安装我的应用程序的特定存储库上引发的 pull 请求事件识别应用程序的特定 installation_id。

我不知道我错过了什么。

最佳答案

如果您的 CI/CD 不适用于 GitHub 的 webhook(例如,由于防火墙),您可以执行以下操作:

#!/bin/bash

HEADER=$( echo -n {\"alg\":\"RS256\"} | base64 | tr -d '=' )
PAYLOAD=$( echo -n \{\"iat\":$(date -u '+%s'),\"exp\":$(( $( date -u '+%s' ) + 600 )),\"iss\":$GITHUB_APP_ID\} | base64 | tr -d '\n' | tr -d '=' | tr / _ | tr + - )
SIGNATURE=$( echo -n "$HEADER.$PAYLOAD" | openssl dgst -sha256 -sign ./private_key -binary | openssl base64 | tr -d '\n' | tr -d '=' | tr / _ | tr + - )
TOKEN=$HEADER.$PAYLOAD.$SIGNATURE

INSTALLATION_ID=$( curl -s -H "Authorization: Bearer $TOKEN" -H "Accept: application/vnd.github.v3+json" https://api.github.com/app/installations | jq .[0].id )
INSTALLATION_TOKEN=$( curl -s -H "Authorization: Bearer $TOKEN" -H "Accept: application/vnd.github.v3+json" -d '{"permissions":{ "checks":"write"}}' https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens | jq .token | tr -d '"' )
echo $INSTALLATION_TOKEN

或者在 Python 中:

# Implementation of: https://docs.github.com/en/developers/apps/authenticating-with-github-apps#authenticating-as-a-github-app
# Inspired by https://gist.github.com/pelson/47c0c89a3522ed8da5cc305afc2562b0

# TL;DR
# Only GitHub App has an access to annotations API. In order to access this API, we need to
# generate a token based on GitHub App's private key and ID. The token (aka JWT) is valid for only 10 min.

import json
import os
import time

import jwt
import requests
from cryptography.hazmat.backends import default_backend

path_to_github_app_key = os.environ["PATH_TO_GITHUB_APP_KEY"]
cert_bytes = open(path_to_github_app_key, "r").read().encode()
github_app_id = os.environ["GITHUB_APP_ID"]
private_key = default_backend().load_pem_private_key(cert_bytes, None)
time_since_epoch_in_seconds = int(time.time())

payload = {
    # issued at time, 60 seconds in the past to allow for clock drift
    "iat": time_since_epoch_in_seconds - 60,
    # JWT expiration time (10 minute maximum)
    "exp": time_since_epoch_in_seconds + (10 * 60),
    # GitHub App's identifier
    "iss": github_app_id,
}

encoded_payload = jwt.encode(payload, private_key, algorithm="RS256")

headers = {
    "Authorization": "Bearer {}".format(encoded_payload),
    "Accept": "application/vnd.github.v3+json",
}

resp = requests.get("https://api.github.com/app/installations", headers=headers)

installation_id = json.loads(resp.content.decode())[0]["id"]

data = '{"permissions":{ "checks":"write"}}'
resp = requests.post(
    "https://api.github.com/app/installations/"
    + str(installation_id)
    + "/access_tokens",
    headers=headers,
    data=data,
)

installation_token = json.loads(resp.content.decode())["token"]
print(installation_token)

我花了一段时间,但这段代码有效。您需要有 GITHUB_APP_ID 和包含 GitHub 生成的私钥的文件 private_key

然后您可以像这样编辑检查运行:

curl -s -H "Authorization: token $GITHUB_APP_INSTALLATION_TOKEN" -H "application/vnd.github.v3+json" -d @body.json https://api.github.com/<username/organization>/$GITHUB_REPO/check-runs

其中 body.json 是一个 JSON 文件,包含以下数据:https://developer.github.com/v3/checks/runs/

例如:

# Create check "Linter" and set its status to "queued".
# https://developer.github.com/v3/checks/runs/

import json
import os

import requests

github_repo = os.environ["GITHUB_REPO"]
github_token = os.environ["GITHUB_APP_INSTALLATION_TOKEN"]
head_sha = os.environ["COMMIT_SHA"]

check = {
    "name": "Linter",
    "head_sha": head_sha,
    "status": "queued",
    "output": {
        "title": "Waiting...",
        "summary": "Check code with linter",
        "text": "Execute 'golangci-lint run'",
    },
}
data = json.dumps(check)

headers = {
    "Authorization": "token " + github_token,
    "Accept": "application/vnd.github.v3+json",
}

# Send request to GitHub.
requests.post(
    "https://api.github.com/repos/<username/organization>/" + github_repo + "/check-runs",
    headers=headers,
    data=data,
)

关于git - 如何在 pull 请求事件中获取 github 应用程序安装 ID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57960709/

相关文章:

java - 在我的 Java 文件 (Eclipse) 中引用一个 git 存储库

git - 我的自定义 git 子命令已停止工作

javascript - 如何使用 Gist API 解析响应内容?

git - 如何找出哪些版本包含给定的 GIT 提交?

github - 如何列出存储库的版本?

github - 如何获得所有超过 20 颗星的公共(public) GitHub 存储库的列表?

xml - 我怎样才能让 git 忽略 Atmel Studio 的 .cproj 文件的某些部分?

git - 如何让我的别名正确完成?

javascript - GitHub 在浏览存储库时如何实现其奇特的页面删除效果?

node.js - 如何从Github API获取私有(private)组织存储库列表?