Skip to content

Commit 29eecef

Browse files
authored
feat: Restrict DAG maxtext_e2e_tests to GitHub schedule events (GoogleCloudPlatform#1315)
This change restricts the DAG `maxtext_e2e_tests` to prevent accidental manual runs from the Airflow UI, as part of a coordinated change with the `maxtext` repository to restrict E2E test triggers.
1 parent dd9de10 commit 29eecef

2 files changed

Lines changed: 74 additions & 27 deletions

File tree

dags/multipod/maxtext_e2e_tests.py

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
repository_dispatch callback with the aggregated result.
1919
"""
2020
import datetime
21-
import requests
2221
from airflow import models
2322
from airflow.models.param import Param
2423
from airflow.operators.python import PythonOperator
2524
from airflow.operators.trigger_dagrun import TriggerDagRunOperator
2625
from airflow.utils.trigger_rule import TriggerRule
26+
from xlml.utils.github import fire_github_callback, validate_git_trigger
2727

2828
with models.DAG(
2929
dag_id="maxtext_e2e_tests",
@@ -79,35 +79,19 @@
7979
poke_interval=600, # check every 10 minutes for child DAG completion
8080
)
8181

82-
def fire_github_callback(**context):
83-
params = context["params"]
84-
dag_run = context["dag_run"]
85-
86-
response = requests.post(
87-
f"https://api.github.com/repos/{params['github_repo']}/dispatches",
88-
headers={
89-
"Authorization": f"Bearer {params['github_callback_token']}",
90-
"Accept": "application/vnd.github+json",
91-
"X-GitHub-Api-Version": "2022-11-28",
92-
},
93-
json={
94-
"event_type": "airflow-dag-complete",
95-
"client_payload": {
96-
"state": "success",
97-
"dag_id": dag_run.dag_id,
98-
"dag_run_id": dag_run.run_id,
99-
"sha": params["maxtext_sha"],
100-
"github_run_id": params["github_run_id"],
101-
},
102-
},
103-
timeout=30,
104-
)
105-
response.raise_for_status()
106-
10782
github_callback = PythonOperator(
10883
task_id="fire_github_callback",
10984
python_callable=fire_github_callback,
11085
trigger_rule=TriggerRule.ALL_SUCCESS, # Only fire if all upstream tasks succeeded
11186
)
11287

113-
[trigger_pre_training, trigger_post_training] >> github_callback
88+
validate_task = PythonOperator(
89+
task_id="validate_trigger",
90+
python_callable=validate_git_trigger,
91+
)
92+
93+
(
94+
validate_task
95+
>> [trigger_pre_training, trigger_post_training]
96+
>> github_callback
97+
)

xlml/utils/github.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Utilities for GitHub API integration."""
16+
17+
import requests
18+
from airflow.exceptions import AirflowFailException
19+
20+
21+
def validate_git_trigger(**context):
22+
"""Validates that the DAG run has required GitHub parameters.
23+
24+
Prevents manual runs from the Airflow UI by ensuring github_run_id,
25+
github_repo, and github_callback_token are present.
26+
"""
27+
params = context["params"]
28+
run_id = params.get("github_run_id")
29+
repo = params.get("github_repo")
30+
token = params.get("github_callback_token")
31+
32+
if not run_id or not repo or not token:
33+
raise AirflowFailException(
34+
"Missing required GitHub parameters (run_id, repo, token). "
35+
"This DAG should not be run manually from the Airflow UI."
36+
)
37+
38+
39+
def fire_github_callback(**context):
40+
"""Fires a GitHub repository_dispatch callback with the DAG run result."""
41+
params = context["params"]
42+
dag_run = context["dag_run"]
43+
44+
response = requests.post(
45+
f"https://api.github.com/repos/{params['github_repo']}/dispatches",
46+
headers={
47+
"Authorization": f"Bearer {params['github_callback_token']}",
48+
"Accept": "application/vnd.github+json",
49+
"X-GitHub-Api-Version": "2022-11-28",
50+
},
51+
json={
52+
"event_type": "airflow-dag-complete",
53+
"client_payload": {
54+
"state": "success",
55+
"dag_id": dag_run.dag_id,
56+
"dag_run_id": dag_run.run_id,
57+
"sha": params["maxtext_sha"],
58+
"github_run_id": params["github_run_id"],
59+
},
60+
},
61+
timeout=30,
62+
)
63+
response.raise_for_status()

0 commit comments

Comments
 (0)