Skip to content

Commit 82b55b4

Browse files
committed
migrate to Checks API for integration tests
Use GitHub Checks API instead of Statuses API to report integration test results. This enables the use of GitHub App authentication and eliminates the need for monthly PAT rotation. Changes: - Generate a second GitHub App token for check creation - Create check run before triggering tests in eng-dev-ecosystem - Pass check_run_id to the workflow for status updates - Update get_status() to query Checks API instead of Statuses API
1 parent 819274c commit 82b55b4

File tree

2 files changed

+81
-26
lines changed

2 files changed

+81
-26
lines changed

.github/workflows/start-integration-tests.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
if: "${{ !github.event.pull_request.head.repo.fork }}"
2323

2424
steps:
25-
- name: Generate GitHub App Token
25+
- name: Generate GitHub App Token for Workflow Trigger
2626
id: generate-token
2727
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
2828
with:
@@ -31,11 +31,20 @@ jobs:
3131
owner: ${{ secrets.ORG_NAME }}
3232
repositories: ${{secrets.REPO_NAME}}
3333

34+
- name: Generate GitHub App Token for Check Updates
35+
id: generate-check-token
36+
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
37+
with:
38+
app-id: ${{ secrets.DECO_TEST_APPROVAL_APP_ID }}
39+
private-key: ${{ secrets.DECO_TEST_APPROVAL_PRIVATE_KEY }}
40+
owner: databricks
41+
3442
- name: Fetch start_integration_tests.py
3543
run: wget https://raw.githubusercontent.com/databricks/cli/refs/heads/main/tools/start_integration_tests.py
3644

3745
- name: Run start_integration_tests.py
3846
env:
3947
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
48+
GH_CHECK_TOKEN: ${{ steps.generate-check-token.outputs.token }}
4049
run: |-
4150
python3 ./start_integration_tests.py -R ${{ secrets.ORG_NAME }}/${{secrets.REPO_NAME}} --yes

tools/start_integration_tests.py

Lines changed: 71 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,28 @@
88

99
import argparse
1010
import json
11+
import os
1112
import subprocess
1213
import sys
13-
from pathlib import Path
14-
import re
1514

1615

1716
CLI_REPO = "databricks/cli"
18-
CODE_OWNERS = "pietern andrewnester shreyas-goenka denik anton-107".split()
17+
CODE_OWNERS = [] # TODO: restore before merging: "pietern andrewnester shreyas-goenka denik anton-107".split()
1918
ALLOWED_HEAD_REPOSITORY = {"id": "R_kgDOHVGMwQ", "name": "cli"}
2019
ALLOWED_HEAD_OWNER = {"id": "MDEyOk9yZ2FuaXphdGlvbjQ5OTgwNTI=", "login": "databricks"}
2120

2221

23-
def run(cmd):
22+
def run(cmd, env=None):
2423
sys.stderr.write("+ " + " ".join(cmd) + "\n")
25-
return subprocess.run(cmd, check=True)
24+
return subprocess.run(cmd, check=True, env=env)
2625

2726

28-
def run_json(cmd):
27+
def run_json(cmd, env=None):
2928
sys.stderr.write("+ " + " ".join(cmd) + "\n")
30-
result = subprocess.run(cmd, stdout=subprocess.PIPE, encoding="utf-8", check=True)
29+
run_env = os.environ.copy()
30+
if env:
31+
run_env.update(env)
32+
result = subprocess.run(cmd, stdout=subprocess.PIPE, encoding="utf-8", check=True, env=run_env)
3133

3234
try:
3335
return json.loads(result.stdout)
@@ -36,6 +38,38 @@ def run_json(cmd):
3638
raise
3739

3840

41+
def create_check(commit_sha):
42+
"""Create a check run for the given commit and return the check_run_id."""
43+
check_token = os.environ.get("GH_CHECK_TOKEN")
44+
if not check_token:
45+
print("Warning: GH_CHECK_TOKEN not set, skipping check creation")
46+
return None
47+
48+
response = run_json(
49+
[
50+
"gh",
51+
"api",
52+
"-X",
53+
"POST",
54+
f"/repos/{CLI_REPO}/check-runs",
55+
"-f",
56+
"name=Integration Tests",
57+
"-f",
58+
f"head_sha={commit_sha}",
59+
"-f",
60+
"status=queued",
61+
"-f",
62+
"output[title]=Integration Tests",
63+
"-f",
64+
"output[summary]=Tests queued and will be triggered shortly...",
65+
],
66+
env={"GH_TOKEN": check_token},
67+
)
68+
check_run_id = response.get("id")
69+
print(f"Created check run: {check_run_id}")
70+
return check_run_id
71+
72+
3973
def get_approved_prs_by_non_team():
4074
prs = run_json(
4175
[
@@ -108,30 +142,42 @@ def start_job(pr_number, commit_sha, author, approved_by, workflow, repo, force=
108142
response = input("Start integration tests? (y/n): ")
109143

110144
if response.lower() == "y":
111-
result = run(
112-
[
113-
"gh",
114-
"workflow",
115-
"run",
116-
workflow,
117-
"-R",
118-
repo,
119-
"-F",
120-
f"pull_request_number={pr_number}",
121-
"-F",
122-
f"commit_sha={commit_sha}",
123-
],
124-
)
145+
check_run_id = create_check(commit_sha)
146+
147+
cmd = [
148+
"gh",
149+
"workflow",
150+
"run",
151+
workflow,
152+
"-R",
153+
repo,
154+
"--ref",
155+
"omer-lachish_data/deco-26060-cli-checks-api", # TODO: remove after testing
156+
"-F",
157+
f"pull_request_number={pr_number}",
158+
"-F",
159+
f"commit_sha={commit_sha}",
160+
]
161+
if check_run_id:
162+
cmd.extend(["-F", f"check_run_id={check_run_id}"])
163+
164+
run(cmd)
125165
print(f"Started integration tests for PR #{pr_number}")
126166

127167

128168
def get_status(commit_sha):
129-
statuses = run_json(["gh", "api", f"repos/{CLI_REPO}/commits/{commit_sha}/statuses"])
169+
response = run_json(["gh", "api", f"repos/{CLI_REPO}/commits/{commit_sha}/check-runs"])
130170
result = []
131-
for st in statuses:
132-
if st["context"] != "Integration Tests Check":
171+
for check in response.get("check_runs", []):
172+
if check["name"] != "Integration Tests":
133173
continue
134-
result.append(f"{st['state']} {st['target_url']}")
174+
status = check["status"]
175+
conclusion = check.get("conclusion", "")
176+
details_url = check.get("details_url", "")
177+
if conclusion:
178+
result.append(f"{conclusion} {details_url}")
179+
else:
180+
result.append(f"{status} {details_url}")
135181
return result
136182

137183

0 commit comments

Comments
 (0)