Skip to content

Commit 5b03df4

Browse files
committed
feat: reuse release workflows for all bot interactions
1 parent 1c4bac1 commit 5b03df4

6 files changed

Lines changed: 216 additions & 213 deletions

File tree

.github/scripts/dispatch_release.py

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,15 @@ def github_api_request(
6161
return resp.status, resp.read().decode("utf-8")
6262

6363

64-
def run_local(workflow: str, kernel_name: str, *, skip_build: bool = False) -> bool:
64+
def run_local(
65+
workflow: str,
66+
kernel_name: str,
67+
*,
68+
skip_build: bool = False,
69+
pr_number: str = "",
70+
target_branch: str = "",
71+
upload: bool = True,
72+
) -> bool:
6573
"""Run a release workflow locally via act."""
6674
cmd = [
6775
"act", "workflow_dispatch",
@@ -71,6 +79,12 @@ def run_local(workflow: str, kernel_name: str, *, skip_build: bool = False) -> b
7179
]
7280
if skip_build:
7381
cmd.extend(["--input", "skip_build=true"])
82+
if pr_number:
83+
cmd.extend(["--input", f"pr_number={pr_number}"])
84+
if target_branch:
85+
cmd.extend(["--input", f"target_branch={target_branch}"])
86+
if not upload:
87+
cmd.extend(["--input", "upload=false"])
7488
print(f"Running locally: {' '.join(cmd)}")
7589
result = subprocess.run(cmd)
7690
return result.returncode == 0
@@ -175,6 +189,9 @@ def dispatch_release(
175189
dispatch_key_prefix: str = "",
176190
local: bool = False,
177191
skip_build: bool = False,
192+
pr_number: str = "",
193+
target_branch: str = "",
194+
upload: bool = True,
178195
) -> ReleaseDispatchResult:
179196
"""
180197
Dispatch the appropriate release workflows for a kernel.
@@ -185,6 +202,11 @@ def dispatch_release(
185202
repo: GitHub repository in "owner/repo" format.
186203
ref: Git ref to dispatch against (default "main").
187204
dispatch_key_prefix: Optional prefix for dispatch keys (e.g. "pr42-").
205+
local: Run locally via act instead of remote dispatch.
206+
skip_build: Skip build and upload steps.
207+
pr_number: Optional PR number to checkout before building.
208+
target_branch: Target branch for upload.
209+
upload: Whether to upload after build.
188210
189211
Returns:
190212
ReleaseDispatchResult with dispatched/failed/skipped lists.
@@ -208,7 +230,13 @@ def dispatch_release(
208230
f"{dispatch_key_prefix}{kernel_name}-{workflow}-{uuid.uuid4().hex[:12]}"
209231
)
210232
if local:
211-
if run_local(workflow, kernel_name, skip_build=skip_build):
233+
if run_local(
234+
workflow, kernel_name,
235+
skip_build=skip_build,
236+
pr_number=pr_number,
237+
target_branch=target_branch,
238+
upload=upload,
239+
):
212240
result.dispatched.append((workflow, dispatch_key))
213241
else:
214242
result.failed.append((workflow, 0))
@@ -220,6 +248,12 @@ def dispatch_release(
220248
}
221249
if skip_build:
222250
inputs["skip_build"] = "true"
251+
if pr_number:
252+
inputs["pr_number"] = pr_number
253+
if target_branch:
254+
inputs["target_branch"] = target_branch
255+
if not upload:
256+
inputs["upload"] = "false"
223257
dispatch_body = {
224258
"ref": ref,
225259
"inputs": inputs,
@@ -255,16 +289,35 @@ def main() -> int:
255289
"--skip-build", action="store_true",
256290
help="Skip build and upload steps (for testing workflow plumbing)",
257291
)
292+
parser.add_argument(
293+
"--pr-number", default="",
294+
help="PR number to checkout before building",
295+
)
296+
parser.add_argument(
297+
"--target-branch", default="",
298+
help="Target branch for upload",
299+
)
300+
parser.add_argument(
301+
"--no-upload", action="store_true",
302+
help="Build only, do not upload",
303+
)
258304
args = parser.parse_args()
259305

306+
common = dict(
307+
skip_build=args.skip_build,
308+
pr_number=args.pr_number,
309+
target_branch=args.target_branch,
310+
upload=not args.no_upload,
311+
)
312+
260313
if args.local:
261314
result = dispatch_release(
262315
args.kernel_name,
263316
token="",
264317
repo="",
265318
ref=args.ref,
266319
local=True,
267-
skip_build=args.skip_build,
320+
**common,
268321
)
269322
else:
270323
token = get_token()
@@ -288,7 +341,7 @@ def main() -> int:
288341
token=token,
289342
repo=repo,
290343
ref=args.ref,
291-
skip_build=args.skip_build,
344+
**common,
292345
)
293346

294347
if result.dispatched:

.github/scripts/pr_comment_kernel_bot.py

Lines changed: 25 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
}
2525
FORK_BLOCKED_COMMANDS = {"build", "build-and-upload", "release"}
2626
MAX_COMMENT_LENGTH = 1024
27-
DISPATCH_WORKFLOW = "manual-build-upload.yaml"
2827
RUN_LOOKUP_ATTEMPTS = 10
2928
RUN_LOOKUP_SLEEP_SECONDS = 2
3029
RUN_LOOKUP_PAGE_SIZE = 100
@@ -222,7 +221,7 @@ def resolve_dispatch_run_urls(
222221
return
223222

224223
if workflows is None:
225-
workflows = [DISPATCH_WORKFLOW]
224+
workflows = RELEASE_WORKFLOWS
226225

227226
for attempt in range(RUN_LOOKUP_ATTEMPTS):
228227
for workflow in workflows:
@@ -295,7 +294,7 @@ def comment_base_lines(
295294
]
296295
if pr_head_sha:
297296
lines.append(f"PR head SHA: `{pr_head_sha}`")
298-
lines.append(f"Workflow: `{DISPATCH_WORKFLOW}`")
297+
lines.append(f"Workflows: `{', '.join(RELEASE_WORKFLOWS)}`")
299298
return lines
300299

301300

@@ -543,27 +542,22 @@ def main():
543542
)
544543
return 0
545544

546-
dispatch_url = f"{api_base}/actions/workflows/{DISPATCH_WORKFLOW}/dispatches"
547545
if command == "build":
548546
target_branch = requested_branch or f"pr-{issue_number}"
549547
dispatch_pr_number = str(issue_number)
550-
upload_flag = "false"
551-
allow_main_dispatch = "false"
548+
dispatch_upload = False
552549
elif command == "build-and-upload":
553550
target_branch = requested_branch or f"pr-{issue_number}"
554551
dispatch_pr_number = str(issue_number)
555-
upload_flag = "true"
556-
allow_main_dispatch = "false"
552+
dispatch_upload = True
557553
elif command == "release":
558-
target_branch = requested_branch or default_branch
554+
target_branch = requested_branch or ""
559555
dispatch_pr_number = ""
560-
upload_flag = "true"
561-
allow_main_dispatch = "true"
562-
else:
556+
dispatch_upload = True
557+
else: # merge-and-upload
563558
target_branch = requested_branch or "main"
564559
dispatch_pr_number = ""
565-
upload_flag = "true"
566-
allow_main_dispatch = "true"
560+
dispatch_upload = True
567561

568562
mode_text = {
569563
"build": "build only",
@@ -658,55 +652,31 @@ def main():
658652
dispatches = []
659653
failed = []
660654

661-
if command == "release":
662-
for kernel_name in kernels:
663-
release_result = do_dispatch_release(
664-
kernel_name,
665-
token=token,
666-
repo=repository,
667-
ref=default_branch,
668-
dispatch_key_prefix=f"pr{issue_number}-",
655+
for kernel_name in kernels:
656+
release_result = do_dispatch_release(
657+
kernel_name,
658+
token=token,
659+
repo=repository,
660+
ref=default_branch,
661+
dispatch_key_prefix=f"pr{issue_number}-",
662+
pr_number=dispatch_pr_number,
663+
target_branch=target_branch,
664+
upload=dispatch_upload,
665+
)
666+
for wf, dk in release_result.dispatched:
667+
dispatches.append(
668+
DispatchResult(kernel_name=f"{kernel_name} ({wf})", dispatch_key=dk)
669669
)
670-
for wf, dk in release_result.dispatched:
671-
dispatches.append(
672-
DispatchResult(kernel_name=f"{kernel_name} ({wf})", dispatch_key=dk)
673-
)
674-
for wf, code in release_result.failed:
675-
failed.append((f"{kernel_name} ({wf})", code))
676-
else:
677-
for kernel_name in kernels:
678-
dispatch_key = make_dispatch_key(issue_number, kernel_name)
679-
dispatch_body = {
680-
"ref": default_branch,
681-
"inputs": {
682-
"kernel_name": kernel_name,
683-
"pr_number": dispatch_pr_number,
684-
"target_branch": target_branch,
685-
"upload": upload_flag,
686-
"allow_main_dispatch": allow_main_dispatch,
687-
"dispatch_key": dispatch_key,
688-
},
689-
}
690-
try:
691-
print(
692-
f"Dispatching workflow for command `{command}`, kernel `{kernel_name}`, branch `{target_branch}`"
693-
)
694-
github_api_request(dispatch_url, token, method="POST", data=dispatch_body)
695-
dispatches.append(
696-
DispatchResult(kernel_name=kernel_name, dispatch_key=dispatch_key)
697-
)
698-
except urllib.error.HTTPError as e:
699-
err_text = e.read().decode("utf-8", errors="replace")
700-
print(err_text, file=sys.stderr)
701-
failed.append((kernel_name, e.code))
670+
for wf, code in release_result.failed:
671+
failed.append((f"{kernel_name} ({wf})", code))
702672

703673
resolve_dispatch_run_urls(
704674
api_base,
705675
token,
706676
repository,
707677
default_branch,
708678
dispatches,
709-
workflows=RELEASE_WORKFLOWS if command == "release" else None,
679+
workflows=RELEASE_WORKFLOWS,
710680
)
711681

712682
comment_written = try_send_issue_comment(

.github/workflows/build-release-mac.yaml

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,21 @@ on:
1717
required: false
1818
type: boolean
1919
default: false
20+
pr_number:
21+
description: "Optional PR number to checkout before building"
22+
required: false
23+
type: string
24+
default: ""
25+
target_branch:
26+
description: "Target branch for upload (default: repo default)"
27+
required: false
28+
type: string
29+
default: ""
30+
upload:
31+
description: "Whether to upload after build"
32+
required: false
33+
type: boolean
34+
default: true
2035
concurrency:
2136
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
2237
cancel-in-progress: true
@@ -25,7 +40,24 @@ jobs:
2540
build-kernel:
2641
runs-on: macos-26
2742
steps:
28-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
43+
- name: Validate PR number
44+
if: inputs.pr_number != ''
45+
run: |
46+
case "${{ inputs.pr_number }}" in
47+
''|*[!0-9]*)
48+
echo "Invalid pr_number input: must be numeric"
49+
exit 1
50+
;;
51+
esac
52+
- name: Checkout PR branch
53+
if: inputs.pr_number != ''
54+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
55+
with:
56+
ref: refs/pull/${{ inputs.pr_number }}/head
57+
fetch-depth: 0
58+
- name: Checkout default branch
59+
if: inputs.pr_number == ''
60+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2961
- uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25 # v22
3062
with:
3163
extra-conf: |
@@ -58,16 +90,20 @@ jobs:
5890
KERNEL="${{ steps.validate.outputs.kernel }}"
5991
( cd "$KERNEL" && nix build -L )
6092
- name: Upload kernel to Hub
61-
if: steps.validate.outputs.skip == 'false' && inputs.skip_build != true
93+
if: steps.validate.outputs.skip == 'false' && inputs.skip_build != true && inputs.upload != false
6294
env:
6395
HF_TOKEN: ${{ secrets.HF_TOKEN }}
6496
run: |
6597
KERNEL="${{ steps.validate.outputs.kernel }}"
6698
cd "$KERNEL"
67-
nix run -L github:huggingface/kernels#kernel-builder -- upload --repo-type model --repo-id "kernels-community/$KERNEL"
68-
nix run -L github:huggingface/kernels#kernel-builder -- upload --repo-type kernel --repo-id "kernels-community/$KERNEL"
99+
BRANCH_FLAG=""
100+
if [ -n "${{ inputs.target_branch }}" ]; then
101+
BRANCH_FLAG="--branch ${{ inputs.target_branch }}"
102+
fi
103+
nix run -L github:huggingface/kernels#kernel-builder -- upload --repo-type model --repo-id "kernels-community/$KERNEL" $BRANCH_FLAG
104+
nix run -L github:huggingface/kernels#kernel-builder -- upload --repo-type kernel --repo-id "kernels-community/$KERNEL" $BRANCH_FLAG
69105
- name: Upload v1 kernels to main
70-
if: steps.validate.outputs.skip == 'false' && inputs.skip_build != true
106+
if: steps.validate.outputs.skip == 'false' && inputs.skip_build != true && inputs.upload != false && inputs.target_branch == ''
71107
env:
72108
HF_TOKEN: ${{ secrets.HF_TOKEN }}
73109
run: |

0 commit comments

Comments
 (0)