name: DSW Document Template Translation Sync

on:
  pull_request:
    branches: [__VERSION_BRANCH__]
  push:
    branches: [__VERSION_BRANCH__]
  workflow_dispatch:

permissions:
  contents: write
  statuses: write

concurrency:
  group: >-
    document-template-translation-sync-${{ github.event_name == 'pull_request' &&
    github.event.pull_request.head.ref || '__VERSION_BRANCH__' }}
  cancel-in-progress: false

env:
  TOOLING_REPOSITORY: __TOOLING_REPOSITORY__
  TOOLING_REF: __TOOLING_REF__
  OPERATIONS_BRANCH: __OPERATIONS_BRANCH__

  COMPACT_TEMPLATE_DIR: __COMPACT_TEMPLATE_DIR__
  EXPANDED_TEMPLATE_DIR: __EXPANDED_TEMPLATE_DIR__
  TRANSLATION_TREE_DIR: __TRANSLATION_TREE_DIR__
  SOURCE_TEMPLATE_ID: __SOURCE_TEMPLATE_ID__
  TRANSLATED_TEMPLATE_ORGANIZATION_ID: __TRANSLATED_TEMPLATE_ORGANIZATION_ID__
  TRANSLATED_TEMPLATE_ID: __TRANSLATED_TEMPLATE_ID__
  TRANSLATED_TEMPLATE_VERSION: __TRANSLATED_TEMPLATE_VERSION__
  TRANSLATED_TEMPLATE_NAME: __TRANSLATED_TEMPLATE_NAME__
  TRANSLATED_TEMPLATE_DESCRIPTION: __TRANSLATED_TEMPLATE_DESCRIPTION__
  TRANSLATION_SOURCE_LANG: __TRANSLATION_SOURCE_LANG__
  TRANSLATION_TARGET_LANG: __TRANSLATION_TARGET_LANG__
  TRANSLATION_TARGET_LABEL: __TRANSLATION_TARGET_LABEL__
  PUBLIC_README_PATH: __PUBLIC_README_PATH__
  TRANSLATED_TEMPLATE_DIR: __TRANSLATED_TEMPLATE_DIR__
  TRANSLATED_TEMPLATE_PACKAGE: __TRANSLATED_TEMPLATE_PACKAGE__
  PROJECT_REF: tooling-repo/fixtures/projects/demo/test-project.json
  PROJECT_RENDER_OUTPUT: __PROJECT_RENDER_OUTPUT__
  PROJECT_RENDER_FORMAT_UUID: 68c26e34-5e77-4e15-9bf7-06ff92582257
  DSW_VERSION: __DSW_VERSION__
  DSW_TDK_VERSION: __DSW_TDK_VERSION__
  UPSTREAM_TEMPLATE_PREVIEW_METAMODEL_VERSION: __UPSTREAM_TEMPLATE_PREVIEW_METAMODEL_VERSION__
  PUBLISH_RELEASE_ASSETS: __PUBLISH_RELEASE_ASSETS__
  REFRESH_TRANSLATION_INPUTS: __REFRESH_TRANSLATION_INPUTS__

jobs:
  translation-sync:
    if: >-
      (github.event_name == 'workflow_dispatch' ||
      github.event_name == 'push' ||
      github.event.pull_request.head.repo.full_name == github.repository)
    runs-on: ubuntu-latest

    steps:
      - name: Checkout template repository
        uses: actions/checkout@v7
        with:
          repository: >-
            ${{ github.event_name == 'pull_request' &&
            github.event.pull_request.head.repo.full_name || github.repository }}
          ref: >-
            ${{ github.event_name == 'pull_request' &&
            github.event.pull_request.head.sha || '__VERSION_BRANCH__' }}
          path: template-repo
          fetch-depth: 0
          persist-credentials: false

      - name: Checkout DSW document-template tooling
        id: tooling_checkout
        uses: actions/checkout@v7
        with:
          repository: ${{ env.TOOLING_REPOSITORY }}
          ref: ${{ env.TOOLING_REF }}
          path: tooling-repo
          persist-credentials: false

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: "3.11"

      - name: Install tooling dependencies
        working-directory: tooling-repo
        run: make install-dev BOOTSTRAP_PYTHON=python

      - name: Install matching dsw-tdk
        working-directory: tooling-repo
        run: |
          .venv/bin/python -m pip install "dsw-tdk==$DSW_TDK_VERSION"
          .venv/bin/dsw-tdk --version

      - name: Regenerate expanded template
        run: |
          set -euo pipefail
          HOST_ROOT="$GITHUB_WORKSPACE/template-repo"
          TOOL_ROOT="$GITHUB_WORKSPACE/tooling-repo"

          "$TOOL_ROOT/.venv/bin/dsw-template-transform" expand \
            --source "$HOST_ROOT/$COMPACT_TEMPLATE_DIR" \
            --output "$HOST_ROOT/$EXPANDED_TEMPLATE_DIR"

      - name: Refresh translation tree
        if: ${{ env.REFRESH_TRANSLATION_INPUTS == 'true' }}
        run: |
          set -euo pipefail
          HOST_ROOT="$GITHUB_WORKSPACE/template-repo"
          TOOL_ROOT="$GITHUB_WORKSPACE/tooling-repo"
          FRESH_TRANSLATION_TREE="$(mktemp -d)"
          MERGED_TRANSLATION_TREE="$(mktemp -d)"

          "$TOOL_ROOT/.venv/bin/dsw-template-tree" export \
            --source "$HOST_ROOT/$EXPANDED_TEMPLATE_DIR" \
            --output "$FRESH_TRANSLATION_TREE"

          if [ -f "$HOST_ROOT/$TRANSLATION_TREE_DIR/.translation-tree/manifest.json" ]; then
            "$TOOL_ROOT/.venv/bin/dsw-template-tree" merge \
              --old-tree "$HOST_ROOT/$TRANSLATION_TREE_DIR" \
              --new-tree "$FRESH_TRANSLATION_TREE" \
              --output "$MERGED_TRANSLATION_TREE" \
              --source-lang "$TRANSLATION_SOURCE_LANG" \
              --target-lang "$TRANSLATION_TARGET_LANG"
          else
            cp -a "$FRESH_TRANSLATION_TREE/." "$MERGED_TRANSLATION_TREE/"
          fi

          rm -rf "$HOST_ROOT/$TRANSLATION_TREE_DIR"
          mkdir -p "$HOST_ROOT/$TRANSLATION_TREE_DIR"
          cp -a "$MERGED_TRANSLATION_TREE/." "$HOST_ROOT/$TRANSLATION_TREE_DIR/"

      - name: Auto-commit repaired translation inputs
        id: auto_commit
        if: >-
          ${{
            env.REFRESH_TRANSLATION_INPUTS == 'true' &&
            github.actor != 'github-actions[bot]'
          }}
        working-directory: template-repo
        env:
          GH_TOKEN: ${{ github.token }}
          TARGET_REF: >-
            ${{ github.event_name == 'pull_request' &&
            github.event.pull_request.head.ref || '__VERSION_BRANCH__' }}
        run: |
          set -euo pipefail
          required_paths=(
            "$EXPANDED_TEMPLATE_DIR"
            "$TRANSLATION_TREE_DIR/.translation-tree/manifest.json"
            "$TRANSLATION_TREE_DIR/README.md"
            "$TRANSLATION_TREE_DIR/outline.md"
            "$TRANSLATION_TREE_DIR/tree"
          )

          if [ -z "$(git status --short -- "${required_paths[@]}")" ]; then
            echo "No generated translation input repairs to commit."
            exit 0
          fi

          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git add \
            "$EXPANDED_TEMPLATE_DIR" \
            "$TRANSLATION_TREE_DIR/.translation-tree/manifest.json" \
            "$TRANSLATION_TREE_DIR/README.md" \
            "$TRANSLATION_TREE_DIR/outline.md" \
            "$TRANSLATION_TREE_DIR/tree"
          git commit -m "chore(sync): refresh document template translations"
          echo "repaired_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
          auth_header="AUTHORIZATION: basic $(printf 'x-access-token:%s' "$GH_TOKEN" | base64 -w0)"
          git -c http.https://github.com/.extraheader="$auth_header" \
            push origin "HEAD:refs/heads/$TARGET_REF"

          {
            echo "## Auto-committed translation repairs"
            echo
            echo "The workflow refreshed generated template/translation inputs and pushed"
            echo "the repair commit back to \`$TARGET_REF\`."
          } >> "$GITHUB_STEP_SUMMARY"

      - name: Check generated translation inputs are committed
        working-directory: template-repo
        run: |
          set -euo pipefail
          # `README.md` documents the generated translation tree and must stay
          # in sync with the exporter output.
          # `outline.md` is a generated progress view. Keep it committed so
          # translators and reviewers can trust its checkbox state.
          # `merge-report.json` is diagnostic metadata; it can change match
          # classification after the first repaired commit without changing any
          # translation content or executable template structure.
          git diff --exit-code -- \
            "$EXPANDED_TEMPLATE_DIR" \
            "$TRANSLATION_TREE_DIR/.translation-tree/manifest.json" \
            "$TRANSLATION_TREE_DIR/README.md" \
            "$TRANSLATION_TREE_DIR/outline.md" \
            "$TRANSLATION_TREE_DIR/tree"
          test -z "$(git status --short -- \
            "$EXPANDED_TEMPLATE_DIR" \
            "$TRANSLATION_TREE_DIR/.translation-tree/manifest.json" \
            "$TRANSLATION_TREE_DIR/README.md" \
            "$TRANSLATION_TREE_DIR/outline.md" \
            "$TRANSLATION_TREE_DIR/tree")"

      - name: Audit translation blocks
        run: |
          set -euo pipefail
          HOST_ROOT="$GITHUB_WORKSPACE/template-repo"
          TOOL_ROOT="$GITHUB_WORKSPACE/tooling-repo"
          AUDIT_LOG="$(mktemp)"

          if ! "$TOOL_ROOT/.venv/bin/dsw-template-tree" audit \
            --tree "$HOST_ROOT/$TRANSLATION_TREE_DIR" \
            --source "$HOST_ROOT/$EXPANDED_TEMPLATE_DIR" 2>&1 | tee "$AUDIT_LOG"; then
            {
              echo "## Translation block audit failed"
              echo
              echo "The translation tree contains blocks that are unsafe for translators."
              echo "Usually this means raw Jinja leaked into a translation.md file or a"
              echo "source unit still needs to be split by the expanded-template rewrite."
              echo
              echo '```text'
              tail -n 120 "$AUDIT_LOG"
              echo '```'
            } >> "$GITHUB_STEP_SUMMARY"

            ERROR_LINE="$(grep -E '^- ' "$AUDIT_LOG" | head -n 1 || true)"
            if [ -n "$ERROR_LINE" ]; then
              echo "::error title=Translation block audit failed::$ERROR_LINE"
            else
              echo "::error title=Translation block audit failed::See job summary for details."
            fi
            exit 1
          fi

      - name: Sync translations into output template
        run: |
          set -euo pipefail
          HOST_ROOT="$GITHUB_WORKSPACE/template-repo"
          TOOL_ROOT="$GITHUB_WORKSPACE/tooling-repo"
          SYNC_LOG="$(mktemp)"

          if ! "$TOOL_ROOT/.venv/bin/dsw-template-tree" sync \
            --tree "$HOST_ROOT/$TRANSLATION_TREE_DIR" \
            --source "$HOST_ROOT/$EXPANDED_TEMPLATE_DIR" \
            --output "$HOST_ROOT/$TRANSLATED_TEMPLATE_DIR" \
            --template-organization-id "$TRANSLATED_TEMPLATE_ORGANIZATION_ID" \
            --template-id "$TRANSLATED_TEMPLATE_ID" \
            --template-name "$TRANSLATED_TEMPLATE_NAME" \
            --template-description "$TRANSLATED_TEMPLATE_DESCRIPTION" \
            --template-version "$TRANSLATED_TEMPLATE_VERSION" \
            --public-readme "$HOST_ROOT/$PUBLIC_README_PATH" 2>&1 | tee "$SYNC_LOG"; then
            {
              echo "## Translation sync failed"
              echo
              echo "The translated template could not be generated. Check the message below;"
              echo "it usually points at the exact translation.md file and placeholder issue."
              echo
              echo '```text'
              tail -n 80 "$SYNC_LOG"
              echo '```'
            } >> "$GITHUB_STEP_SUMMARY"

            ERROR_LINE="$(grep -E 'Translation(TreeError| is | uses | introduces )|Missing translation document|Invalid translation document' "$SYNC_LOG" | tail -n 1 || true)"
            if [ -n "$ERROR_LINE" ]; then
              echo "::error title=Translation sync failed::$ERROR_LINE"
            else
              echo "::error title=Translation sync failed::See job summary for details."
            fi
            exit 1
          fi

          STRUCTURE_LOG="$(mktemp)"
          if ! "$TOOL_ROOT/.venv/bin/dsw-template-tree" audit-output \
            --source "$HOST_ROOT/$EXPANDED_TEMPLATE_DIR" \
            --output "$HOST_ROOT/$TRANSLATED_TEMPLATE_DIR" 2>&1 | tee "$STRUCTURE_LOG"; then
            {
              echo "## Translated output structure audit failed"
              echo
              echo "The translated template changed executable Jinja, HTML wiring,"
              echo "links/assets, or static source assets. This is a structural issue,"
              echo "not a wording issue."
              echo
              echo '```text'
              tail -n 120 "$STRUCTURE_LOG"
              echo '```'
            } >> "$GITHUB_STEP_SUMMARY"

            ERROR_LINE="$(grep -E '^- ' "$STRUCTURE_LOG" | head -n 1 || true)"
            if [ -n "$ERROR_LINE" ]; then
              echo "::error title=Translated output structure audit failed::$ERROR_LINE"
            else
              echo "::error title=Translated output structure audit failed::See job summary for details."
            fi
            exit 1
          fi

          "$TOOL_ROOT/.venv/bin/dsw-tdk" package "$HOST_ROOT/$TRANSLATED_TEMPLATE_DIR" \
            --output "$HOST_ROOT/$TRANSLATED_TEMPLATE_PACKAGE" \
            --force

      - name: Upload translated template package
        uses: actions/upload-artifact@v7
        with:
          name: document-template-package-${{ env.TRANSLATED_TEMPLATE_VERSION }}
          path: |
            template-repo/${{ env.TRANSLATED_TEMPLATE_DIR }}
            template-repo/${{ env.TRANSLATED_TEMPLATE_PACKAGE }}

      # This boots an ephemeral DSW and copies PROJECT_REF into it. By default,
      # the sample project fixture lives in the tooling repo so translation
      # repositories do not need to carry stale demo project or Knowledge Model
      # copies.
      # PROJECT_REF can also point at a JSON recipe or existing project UUID in
      # the checked-out template repo if a public-repository workflow overrides it.
      - name: Start local DSW stack for sample render
        if: ${{ env.PROJECT_REF != '' }}
        working-directory: tooling-repo
        run: make start-ci-dsw

      - name: Render sample project preview
        if: ${{ env.PROJECT_REF != '' }}
        env:
          DSW_API_URL: http://localhost:3000/wizard-api
          DSW_EMAIL: albert.einstein@example.com
          DSW_PASSWORD: password
          DSW_DOWNLOAD_HOST_ALIAS: host.docker.internal=localhost
        run: |
          set -euo pipefail
          HOST_ROOT="$GITHUB_WORKSPACE/template-repo"
          TOOL_ROOT="$GITHUB_WORKSPACE/tooling-repo"
          template_json="$HOST_ROOT/$TRANSLATED_TEMPLATE_DIR/template.json"
          template_metamodel_version="$("$TOOL_ROOT/.venv/bin/python" -c 'import json, sys; print(json.load(open(sys.argv[1], encoding="utf-8")).get("metamodelVersion", ""))' "$template_json")"
          failure_path="$(dirname "$HOST_ROOT/$PROJECT_RENDER_OUTPUT")/failed.json"
          case "$PROJECT_REF" in
            /*) project_ref_path="$PROJECT_REF" ;;
            *) project_ref_path="$GITHUB_WORKSPACE/$PROJECT_REF" ;;
          esac

          set +e
          "$TOOL_ROOT/.venv/bin/dsw-template-render-project" \
            --project-ref "$project_ref_path" \
            --template-package "$HOST_ROOT/$TRANSLATED_TEMPLATE_PACKAGE" \
            --format-uuid "$PROJECT_RENDER_FORMAT_UUID" \
            --output "$HOST_ROOT/$PROJECT_RENDER_OUTPUT" \
            --tdk-executable "$TOOL_ROOT/.venv/bin/dsw-tdk"
          render_status=$?
          set -e

          if [ "$render_status" -ne 0 ]; then
            "$TOOL_ROOT/.venv/bin/python" "$TOOL_ROOT/scripts/ci/write_preview_status.py" \
              --output "$failure_path" \
              --status failed \
              --reason render_failed \
              --template-version "v$TRANSLATED_TEMPLATE_VERSION" \
              --template-metamodel-version "$template_metamodel_version" \
              --preview-metamodel-version "$UPSTREAM_TEMPLATE_PREVIEW_METAMODEL_VERSION" \
              --exit-code "$render_status"
            echo "WARNING: Sample project preview failed; wrote $failure_path"
            exit "$render_status"
          fi

      - name: Run translated package full regression
        if: ${{ env.PROJECT_REF != '' }}
        working-directory: tooling-repo
        env:
          DSW_API_URL: http://localhost:3000/wizard-api
          DSW_EMAIL: albert.einstein@example.com
          DSW_PASSWORD: password
          DSW_DOWNLOAD_HOST_ALIAS: host.docker.internal=localhost
        run: |
          make render-translated-package-regression \
            SOURCE_TEMPLATE_VERSION="$TRANSLATED_TEMPLATE_VERSION" \
            TRANSLATED_REGRESSION_METAMODEL_VERSION="$UPSTREAM_TEMPLATE_PREVIEW_METAMODEL_VERSION" \
            TRANSLATED_REGRESSION_OUTPUT_DIR="$GITHUB_WORKSPACE/template-repo/outputs/translated-regression/$SOURCE_TEMPLATE_ID/v$TRANSLATED_TEMPLATE_VERSION/$TRANSLATION_TARGET_LABEL" \
            TRANSLATED_TEMPLATE_PACKAGE="$GITHUB_WORKSPACE/template-repo/$TRANSLATED_TEMPLATE_PACKAGE"

      - name: Summarize translated package regression coverage
        if: ${{ always() && env.PROJECT_REF != '' }}
        working-directory: tooling-repo
        run: |
          make summarize-regression-coverage \
            REGRESSION_OUTPUT_DIR="$GITHUB_WORKSPACE/template-repo/outputs/translated-regression/$SOURCE_TEMPLATE_ID/v$TRANSLATED_TEMPLATE_VERSION/$TRANSLATION_TARGET_LABEL" \
            REGRESSION_SUMMARY_LABEL="Translated Package Regression Coverage"

      - name: Collect local DSW logs
        if: >-
          ${{
            always() && env.PROJECT_REF != '' &&
            steps.tooling_checkout.outcome == 'success'
          }}
        working-directory: tooling-repo
        run: make ci-dsw-logs

      - name: Stop local DSW stack
        if: >-
          ${{
            always() && env.PROJECT_REF != '' &&
            steps.tooling_checkout.outcome == 'success'
          }}
        working-directory: tooling-repo
        run: make stop-ci-dsw

      - name: Stage sample project preview artifact
        if: ${{ always() && env.PROJECT_REF != '' }}
        run: |
          set -euo pipefail
          artifact_dir="$RUNNER_TEMP/document-template-preview"
          preview_output="$GITHUB_WORKSPACE/template-repo/$PROJECT_RENDER_OUTPUT"
          regression_output="$GITHUB_WORKSPACE/template-repo/outputs/translated-regression/$SOURCE_TEMPLATE_ID/v$TRANSLATED_TEMPLATE_VERSION/$TRANSLATION_TARGET_LABEL"
          rm -rf "$artifact_dir"
          mkdir -p "$artifact_dir"

          for candidate in \
            "$preview_output" \
            "$preview_output.json" \
            "$(dirname "$preview_output")/failed.json" \
            "$regression_output/regression_report.json" \
            "$regression_output/random-project-coverage.json"; do
            if [ -e "$candidate" ] || [ -L "$candidate" ]; then
              if [ ! -f "$candidate" ] || [ -L "$candidate" ]; then
                echo "::error title=Unsafe preview artifact::Expected a regular file: $candidate"
                exit 1
              fi
              cp -- "$candidate" "$artifact_dir/$(basename "$candidate")"
            fi
          done

      - name: Upload sample project preview
        if: ${{ always() && env.PROJECT_REF != '' }}
        uses: actions/upload-artifact@v7
        with:
          name: document-template-preview-${{ env.TRANSLATED_TEMPLATE_VERSION }}
          path: |
            ${{ runner.temp }}/document-template-preview/
            tooling-repo/outputs/ci-dsw/
          if-no-files-found: warn

      - name: Stage translated template release assets
        if: ${{ github.event_name != 'pull_request' && env.PUBLISH_RELEASE_ASSETS == 'true' }}
        run: |
          set -euo pipefail
          HOST_ROOT="$GITHUB_WORKSPACE/template-repo"
          TOOL_ROOT="$GITHUB_WORKSPACE/tooling-repo"
          release_dir="$HOST_ROOT/outputs/release-assets/$SOURCE_TEMPLATE_ID/v$TRANSLATED_TEMPLATE_VERSION/$TRANSLATION_TARGET_LABEL"
          preview_output="$HOST_ROOT/$PROJECT_RENDER_OUTPUT"
          regression_output="$HOST_ROOT/outputs/translated-regression/$SOURCE_TEMPLATE_ID/v$TRANSLATED_TEMPLATE_VERSION/$TRANSLATION_TARGET_LABEL"

          "$TOOL_ROOT/.venv/bin/python" "$TOOL_ROOT/scripts/ci/stage_release_assets.py" \
            --output-dir "$release_dir" \
            --notes-title "$TRANSLATED_TEMPLATE_NAME v$TRANSLATED_TEMPLATE_VERSION" \
            --notes-body "Generated by $GITHUB_REPOSITORY run $GITHUB_RUN_ID from commit $(git -C "$HOST_ROOT" rev-parse HEAD)." \
            --notes-body "The package passed complete generated-fixture render coverage. These CI-built assets are intended for review and manual DSW import." \
            --asset "$HOST_ROOT/$TRANSLATED_TEMPLATE_PACKAGE=$TRANSLATED_TEMPLATE_ORGANIZATION_ID-$TRANSLATED_TEMPLATE_ID-v$TRANSLATED_TEMPLATE_VERSION.zip" \
            --optional-asset "$preview_output=test-project-v$TRANSLATED_TEMPLATE_VERSION.pdf" \
            --optional-asset "$preview_output.json=test-project-v$TRANSLATED_TEMPLATE_VERSION.pdf.json" \
            --optional-asset "$regression_output/regression_report.json=regression-report-v$TRANSLATED_TEMPLATE_VERSION.json" \
            --optional-asset "$regression_output/random-project-coverage.json=regression-coverage-v$TRANSLATED_TEMPLATE_VERSION.json"

      - name: Publish translated template release assets
        if: ${{ github.event_name != 'pull_request' && env.PUBLISH_RELEASE_ASSETS == 'true' }}
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          set -euo pipefail
          HOST_ROOT="$GITHUB_WORKSPACE/template-repo"
          release_dir="$HOST_ROOT/outputs/release-assets/$SOURCE_TEMPLATE_ID/v$TRANSLATED_TEMPLATE_VERSION/$TRANSLATION_TARGET_LABEL"
          release_tag="$TRANSLATED_TEMPLATE_ID-v$TRANSLATED_TEMPLATE_VERSION"
          release_title="$TRANSLATED_TEMPLATE_NAME v$TRANSLATED_TEMPLATE_VERSION"
          release_target="$(git -C "$HOST_ROOT" rev-parse HEAD)"

          edit_release() {
            gh release edit "$release_tag" \
              --repo "$GITHUB_REPOSITORY" \
              --title "$release_title" \
              --notes-file "$release_dir/release-notes.md" \
              --prerelease
          }

          create_release() {
            create_args=(
              "$release_tag"
              --repo "$GITHUB_REPOSITORY"
              --title "$release_title"
              --notes-file "$release_dir/release-notes.md"
              --prerelease
              --latest=false
              --target "$release_target"
            )
            gh release create "${create_args[@]}"
          }

          if gh release view "$release_tag" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
            edit_release
          elif ! create_release; then
            # GitHub release APIs are occasionally eventually consistent. If a
            # concurrent or previous run created the release after our view
            # check, fall back to edit before uploading clobbered assets.
            edit_release
          fi

          gh release upload "$release_tag" "$release_dir"/* --repo "$GITHUB_REPOSITORY" --clobber

      - name: Mark auto-repaired head as validated
        if: ${{ steps.auto_commit.outputs.repaired_sha != '' }}
        env:
          GH_TOKEN: ${{ github.token }}
          REPAIRED_SHA: ${{ steps.auto_commit.outputs.repaired_sha }}
        run: |
          set -euo pipefail
          gh api "repos/$GITHUB_REPOSITORY/statuses/$REPAIRED_SHA" \
            -f state=success \
            -f context="translation-sync / repaired head" \
            -f description="Auto-repaired translation inputs were validated." \
            -f target_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"

  dispatch-operations-migration:
    needs: translation-sync
    if: >-
      github.event_name == 'push' &&
      !startsWith(github.event.head_commit.message, 'chore: refresh ') &&
      !startsWith(github.event.head_commit.message, 'chore(sync): carry ') &&
      !startsWith(github.event.head_commit.message, 'chore(sync): refresh document template translations')
    runs-on: ubuntu-latest
    permissions:
      actions: write

    steps:
      - name: Dispatch operations migration
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          set -euo pipefail
          gh workflow run document_template_translation_sync.yml \
            --repo "$GITHUB_REPOSITORY" \
            --ref "$OPERATIONS_BRANCH" \
            -f source_version="v$TRANSLATED_TEMPLATE_VERSION"

          {
            echo "## Operations migration dispatched"
            echo
            echo "Requested \`$OPERATIONS_BRANCH\` operations migration from"
            echo "\`v$TRANSLATED_TEMPLATE_VERSION\` after this version branch passed."
          } >> "$GITHUB_STEP_SUMMARY"

  skip-fork-pr:
    if: >-
      github.event_name == 'pull_request' &&
      github.event.pull_request.head.repo.full_name != github.repository
    runs-on: ubuntu-latest

    steps:
      - name: Explain fork PR skip policy
        run: echo "Skipping auto-sync commit for fork pull requests."
