|
12 | 12 | # See the License for the specific language governing permissions and |
13 | 13 | # limitations under the License. |
14 | 14 |
|
15 | | -# This workflow will test and promote a MaxText Docker image. |
| 15 | +# This workflow acts as the final gate in the CI/CD pipeline for MaxText Docker images. |
| 16 | +# Triggered by: Airflow DAG completion (repository_dispatch) |
| 17 | +# 1. Validates the result of the triggered Airflow DAG (E2E tests). |
| 18 | +# 2. If the DAG succeeded, it promotes the Docker images by tagging the artifact with the latest tag. |
16 | 19 |
|
17 | 20 | name: Promote MaxText Docker Image |
18 | 21 |
|
19 | 22 | on: |
20 | | - workflow_call: |
21 | | - inputs: |
22 | | - image_name: |
23 | | - required: true |
24 | | - type: string |
25 | | - image_tag: |
26 | | - required: true |
27 | | - type: string |
28 | | - device: |
29 | | - required: true |
30 | | - type: string |
31 | | - workflow: |
32 | | - required: true |
33 | | - type: string |
| 23 | + repository_dispatch: |
| 24 | + types: [airflow-dag-complete] |
| 25 | + |
34 | 26 | permissions: |
35 | 27 | contents: read |
36 | 28 |
|
37 | 29 | jobs: |
38 | | - check_image: |
39 | | - runs-on: linux-x86-n2-16-buildkit |
40 | | - container: google/cloud-sdk:524.0.0 |
41 | | - outputs: |
42 | | - image_exists: ${{ steps.check.outputs.exists }} |
| 30 | + handle_result: |
| 31 | + name: Handle Airflow DAG Result - ${{ github.event.client_payload.dag_id }} |
| 32 | + runs-on: ubuntu-latest |
43 | 33 | steps: |
44 | | - - name: Check if image exists |
45 | | - id: check |
46 | | - shell: bash |
| 34 | + - name: Report DAG result |
47 | 35 | run: | |
48 | | - if gcloud container images describe "gcr.io/${{ vars.PROJECT_NAME }}/${{ inputs.image_name }}:${{ inputs.image_tag }}" >/dev/null 2>&1; then |
49 | | - echo "exists=true" >> $GITHUB_OUTPUT |
50 | | - else |
51 | | - echo "exists=false" >> $GITHUB_OUTPUT |
52 | | - fi |
| 36 | + STATE="${{ github.event.client_payload.state }}" |
| 37 | + DAG_ID="${{ github.event.client_payload.dag_id }}" |
| 38 | + DAG_RUN_ID="${{ github.event.client_payload.dag_run_id }}" |
| 39 | + SHA="${{ github.event.client_payload.sha }}" |
53 | 40 |
|
54 | | - test: |
55 | | - needs: check_image |
56 | | - if: needs.check_image.outputs.image_exists == 'true' |
57 | | - strategy: |
58 | | - fail-fast: false |
59 | | - matrix: |
60 | | - flavor: >- |
61 | | - ${{ fromJSON('{ |
62 | | - "gpu-pre-training": ["gpu-unit", "gpu-integration"], |
63 | | - "tpu-post-training": ["tpu-post-training-unit", "tpu-post-training-integration", "cpu-post-training-unit"], |
64 | | - "tpu-pre-training": ["tpu-unit", "tpu-integration", "cpu-unit"] |
65 | | - }')[format('{0}-{1}', inputs.device, inputs.workflow)] }} |
66 | | - uses: ./.github/workflows/run_tests_coordinator.yml |
67 | | - with: |
68 | | - flavor: ${{ matrix.flavor }} |
69 | | - base_image: ${{ inputs.image_name }}:${{ inputs.image_tag }} |
70 | | - is_scheduled_run: true |
71 | | - maxtext_installed: true |
72 | | - additional_pytest_args: ${{ contains(inputs.image_name, 'maxtext_jax_nightly') && '--ignore=tests/integration/hlo_diff_test.py' || '' }} |
| 41 | + echo "================================" |
| 42 | + echo "DAG ID: ${DAG_ID}" |
| 43 | + echo "DAG Run ID: ${DAG_RUN_ID}" |
| 44 | + echo "Commit SHA: ${SHA}" |
| 45 | + echo "State: ${STATE}" |
| 46 | + echo "================================" |
73 | 47 |
|
74 | | - tagging: |
75 | | - needs: [test] |
76 | | - if: needs.test.result == 'success' |
| 48 | + case "$STATE" in |
| 49 | + success) echo "E2E tests PASSED." ;; |
| 50 | + failed|upstream_failed) echo "E2E tests FAILED."; exit 1 ;; |
| 51 | + *) echo "DAG ended with unexpected state: ${STATE}"; exit 1 ;; |
| 52 | + esac |
| 53 | +
|
| 54 | + tag_docker_image: |
| 55 | + name: Promote ${{ matrix.image_name }} Docker Image |
| 56 | + needs: handle_result |
| 57 | + if: needs.handle_result.result == 'success' |
77 | 58 | runs-on: linux-x86-n2-16-buildkit |
78 | 59 | container: google/cloud-sdk:524.0.0 |
| 60 | + strategy: |
| 61 | + fail-fast: false |
| 62 | + matrix: |
| 63 | + image_name: |
| 64 | + - maxtext_jax_nightly |
| 65 | + - maxtext_gpu_jax_nightly |
| 66 | + - maxtext_post_training_nightly |
79 | 67 | steps: |
80 | 68 | - name: Configure Docker |
81 | 69 | run: gcloud auth configure-docker us-docker.pkg.dev,gcr.io -q |
82 | | - |
83 | 70 | - name: Add tags to Docker image |
84 | 71 | shell: bash |
85 | 72 | run: | |
86 | | - # Add Latest Tag |
87 | | - SOURCE_IMAGE="gcr.io/${{ vars.PROJECT_NAME }}/${{ inputs.image_name }}" |
88 | | - gcloud container images add-tag "${SOURCE_IMAGE}:${{ inputs.image_tag }}" "${SOURCE_IMAGE}:latest" --quiet |
| 73 | + SOURCE_IMAGE="gcr.io/${{ vars.PROJECT_NAME }}/${{ matrix.image_name }}" |
| 74 | + GITHUB_RUN_ID="${{ github.event.client_payload.github_run_id }}" |
| 75 | +
|
| 76 | + # Add the traceability tag to confirm it passed validation suite |
| 77 | + SHORT_DAG_RUN_ID=$(echo "${{ github.event.client_payload.dag_run_id }}" | cut -c1-7) |
| 78 | + gcloud container images add-tag "${SOURCE_IMAGE}:${GITHUB_RUN_ID}" \ |
| 79 | + "${SOURCE_IMAGE}:verified-${SHORT_DAG_RUN_ID}" --quiet |
| 80 | +
|
| 81 | + # Add "latest" tag |
| 82 | + gcloud container images add-tag "${SOURCE_IMAGE}:${GITHUB_RUN_ID}" "${SOURCE_IMAGE}:latest" --quiet |
0 commit comments