Files
flights_web/.gitea/workflows/release.yml
T
gnezim 03eeddfbf8 CI/CD pipeline: ssh -L tunnel for TIM API + manual Jenkins trigger
Two design pivots discovered during Phase B prerequisites:

Routing: Replace static-route + NAT plan with persistent ssh -L tunnel
from pve-201 to webzavod (deployment/systemd/flights-tim-tunnel.service).
nginx proxies /api/ and /map/api/ to https://127.0.0.1:8443 with SNI/Host
overrides so cert validation still targets the real hostname. No webzavod
kernel changes (no ip_forward/MASQUERADE), no /etc/hosts pin needed.

Workflow B: Drop Jenkins trigger/poll automation (operator lacks Jenkins
job-configure access and user API token access). release.yml now stops
after MR merge with a Telegram message containing the Jenkins job URL.
release-verify.yml (new, workflow_dispatch only) runs the customer-URL
e2e suite once the operator has triggered Jenkins manually and it has
completed.

Other:
- SSR loopback port 8081 -> 3002 (8081 was taken by openwebui on pve-201)
- notify-telegram.sh skips cleanly when TG secrets unset (was: hard-fail)
- README + spec addendum cover the new prereqs and removed steps
2026-04-27 11:58:39 +03:00

173 lines
6.7 KiB
YAML

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 e2e the customer URL.
jobs:
release:
runs-on: pve-201
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
run: |
pnpm typecheck
pnpm lint
pnpm test
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"