name: release on: workflow_dispatch: push: tags: - 'release-*' # Workflow B: sync to GitLab + open MR + auto-merge. # Stops at "MR merged" — Jenkins is triggered manually by the operator. # After Jenkins finishes, run the `release-verify` workflow to smoke-check # the customer URL. jobs: release: runs-on: ubuntu-latest timeout-minutes: 30 env: GITLAB_PAT: ${{ secrets.GITLAB_PAT }} GITLAB_PROJECT_ID: ${{ secrets.GITLAB_PROJECT_ID }} GITLAB_HOST: 'https://teamscore.gitlab.yandexcloud.net' GITLAB_PROJECT_PATH: 'aeroflot2/flights-front' JENKINS_JOB_URL: 'http://jenkins.yc.devwebzavod.ru:8080/job/Aeroflot2/job/Flights-Front-Dev/' TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }} TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }} steps: - name: Checkout (full history + tags) uses: actions/checkout@v4 with: fetch-depth: 0 - name: Notify start if: ${{ env.TELEGRAM_BOT_TOKEN != '' }} run: scripts/ci/notify-telegram.sh start release - name: Verify ci-deploy is green for this SHA id: gate run: | API="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/actions/runs?head_sha=${GITHUB_SHA}" resp=$(curl -fsS -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" "$API" || echo '{"workflow_runs":[]}') ok=$(echo "$resp" | jq -r --arg name "ci-deploy" ' .workflow_runs[] | select(.name == $name) | .conclusion ' | head -1) if [ "$ok" != "success" ]; then echo "fatal: ci-deploy is not green for ${GITHUB_SHA} (got: '${ok:-none}')" exit 1 fi echo "ci-deploy green for ${GITHUB_SHA}" - name: Setup Node + pnpm uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' - uses: pnpm/action-setup@v4 - name: Install dependencies run: pnpm install --frozen-lockfile - name: Paranoid re-run — typecheck + lint + unit id: paranoid # Mirror ci-deploy's `--exclude 'tests/eslint/**'`: typescript-eslint's # project cache doesn't see runtime-generated probe files inside the # runner container, so those config-drift guards fail CI-only. run: | pnpm typecheck pnpm lint pnpm test -- --exclude 'tests/eslint/**' pnpm test:ci - name: Clone GitLab target id: clone run: | rm -rf /tmp/flights-front git clone "https://oauth2:${GITLAB_PAT}@teamscore.gitlab.yandexcloud.net/aeroflot2/flights-front.git" /tmp/flights-front mkdir -p /tmp/flights-front/Aeroflot.Flights.Front - name: Sync to GitLab clone id: sync run: scripts/ci/sync-to-gitlab.sh /tmp/flights-front/Aeroflot.Flights.Front - name: Commit on auto branch id: commit run: | cd /tmp/flights-front git config user.email "ci@gnerim.ru" git config user.name "gnerim CI" BRANCH="auto/sync-${GITHUB_SHA:0:7}" git checkout -b "$BRANCH" git add -A if git diff --cached --quiet; then echo "nothing to sync" echo "skip_remaining=1" >> "$GITHUB_OUTPUT" exit 0 fi git commit -m "auto: sync from gitea ${GITHUB_SHA:0:7}" echo "branch=$BRANCH" >> "$GITHUB_OUTPUT" - name: Push branch id: push if: steps.commit.outputs.skip_remaining != '1' run: | cd /tmp/flights-front git push -u origin "${{ steps.commit.outputs.branch }}" - name: Open MR id: mr_open if: steps.commit.outputs.skip_remaining != '1' run: | BRANCH="${{ steps.commit.outputs.branch }}" TITLE="auto: sync from gitea ${GITHUB_SHA:0:7}" BODY="Auto-sync from gitea run: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" resp=$(curl -fsS -X POST \ -H "PRIVATE-TOKEN: ${GITLAB_PAT}" \ -H "Content-Type: application/json" \ -d "$(jq -nc --arg sb "$BRANCH" --arg t "$TITLE" --arg d "$BODY" '{source_branch:$sb, target_branch:"main", title:$t, description:$d, remove_source_branch:true, squash:true}')" \ "${GITLAB_HOST}/api/v4/projects/${GITLAB_PROJECT_ID}/merge_requests") IID=$(echo "$resp" | jq -r '.iid') [ "$IID" != "null" ] || { echo "fatal: MR open failed: $resp" >&2; exit 1; } echo "iid=$IID" >> "$GITHUB_OUTPUT" echo "url=$(echo "$resp" | jq -r '.web_url')" >> "$GITHUB_OUTPUT" - name: Approve MR id: mr_approve if: steps.commit.outputs.skip_remaining != '1' run: | curl -fsS -X POST \ -H "PRIVATE-TOKEN: ${GITLAB_PAT}" \ "${GITLAB_HOST}/api/v4/projects/${GITLAB_PROJECT_ID}/merge_requests/${{ steps.mr_open.outputs.iid }}/approve" \ >/dev/null || { echo "fatal: MR approve failed — verify 'Prevent approval by author' is unchecked" exit 1 } - name: Merge MR id: mr_merge if: steps.commit.outputs.skip_remaining != '1' run: | curl -fsS -X PUT \ -H "PRIVATE-TOKEN: ${GITLAB_PAT}" \ -H "Content-Type: application/json" \ -d '{"merge_when_pipeline_succeeds":false,"should_remove_source_branch":true,"squash":true}' \ "${GITLAB_HOST}/api/v4/projects/${GITLAB_PROJECT_ID}/merge_requests/${{ steps.mr_open.outputs.iid }}/merge" \ >/dev/null - name: Cleanup MR + branch on failure if: failure() && (steps.mr_open.outcome == 'failure' || steps.mr_approve.outcome == 'failure' || steps.mr_merge.outcome == 'failure') run: | IID="${{ steps.mr_open.outputs.iid }}" BRANCH="${{ steps.commit.outputs.branch }}" if [ -n "$IID" ] && [ "$IID" != "null" ]; then curl -fsS -X PUT \ -H "PRIVATE-TOKEN: ${GITLAB_PAT}" \ -H "Content-Type: application/json" \ -d '{"state_event":"close"}' \ "${GITLAB_HOST}/api/v4/projects/${GITLAB_PROJECT_ID}/merge_requests/${IID}" \ >/dev/null || true fi if [ -n "$BRANCH" ]; then curl -fsS -X DELETE \ -H "PRIVATE-TOKEN: ${GITLAB_PAT}" \ "${GITLAB_HOST}/api/v4/projects/${GITLAB_PROJECT_ID}/repository/branches/$(printf '%s' "$BRANCH" | sed 's|/|%2F|g')" \ >/dev/null || true fi - name: Notify (success — manual Jenkins trigger required) if: success() && env.TELEGRAM_BOT_TOKEN != '' run: | MR_URL='${{ steps.mr_open.outputs.url }}' scripts/ci/notify-telegram.sh ok release "MR merged: ${MR_URL}. Now trigger Jenkins manually: ${JENKINS_JOB_URL}, then dispatch the release-verify workflow." - name: Notify (failure) if: failure() && env.TELEGRAM_BOT_TOKEN != '' run: scripts/ci/notify-telegram.sh fail release "see Gitea run"