diff --git a/.github/workflows/distribute-manual.yml b/.github/workflows/distribute-manual.yml index 8c415f0f..b0341fbb 100644 --- a/.github/workflows/distribute-manual.yml +++ b/.github/workflows/distribute-manual.yml @@ -2,10 +2,16 @@ name: Distribute PushOk (manual) on: workflow_dispatch: + inputs: + app_ref: + description: "GitLab App branch (Optional)" + required: false + default: "" jobs: call-reusable: uses: ./.github/workflows/distribute-reusable.yml with: branch: ${{ github.ref_name }} - secrets: inherit \ No newline at end of file + app_ref: ${{ inputs.app_ref }} + secrets: inherit diff --git a/.github/workflows/distribute-reusable.yml b/.github/workflows/distribute-reusable.yml index 85c3f1a4..229fd15f 100644 --- a/.github/workflows/distribute-reusable.yml +++ b/.github/workflows/distribute-reusable.yml @@ -6,6 +6,13 @@ on: branch: required: true type: string + app_ref: + required: false + type: string + default: "" + secrets: + GITLAB_TRIGGER_TOKEN: + required: true jobs: distribution: @@ -16,16 +23,187 @@ jobs: with: ref: ${{ inputs.branch }} submodules: recursive + fetch-depth: 3 - name: Get last 3 commit messages + shell: bash run: | - commits=$(git log -3 --pretty=format:"%s") - echo "commits=$commits" >> $GITHUB_ENV + set -euo pipefail + commits="$(git log -3 --pretty=format:"%s")" + echo "commits<> "$GITHUB_ENV" + echo "$commits" >> "$GITHUB_ENV" + echo "EOF" >> "$GITHUB_ENV" - - name: Trigger build & send to FAD + - name: Debug payload that will be sent to GitLab + shell: bash + env: + SOURCE_BRANCH: ${{ inputs.branch }} + APP_REF_OVERRIDE: ${{ inputs.app_ref }} + DEFAULT_APP_REF: develop + INPUT_COMMITS: ${{ env.commits }} run: | - curl --location 'https://mindbox.gitlab.yandexcloud.net/api/v4/projects/900/trigger/pipeline' \ - --form 'token="${{ secrets.GITLAB_TRIGGER_TOKEN }}"' \ - --form 'ref="develop"' \ - --form "variables[INPUT_BRANCH]=\"${{ inputs.branch }}\"" \ - --form "variables[INPUT_COMMITS]=\"${{ env.commits }}\"" + set -euo pipefail + + # Trim override so " " becomes empty + APP_REF_OVERRIDE="$(printf '%s' "${APP_REF_OVERRIDE:-}" | xargs)" + + echo "---- DEBUG (GitHub -> GitLab trigger payload) ----" + echo "SDK branch (INPUT_BRANCH): $SOURCE_BRANCH" + echo "Manual App ref override: ${APP_REF_OVERRIDE:-}" + echo "Default App ref: $DEFAULT_APP_REF" + echo "" + echo "RAW INPUT_COMMITS (cat -A):" + printf '%s' "${INPUT_COMMITS:-}" | cat -A + echo "" + echo "RAW INPUT_COMMITS (printf %q):" + printf '%q\n' "${INPUT_COMMITS:-}" + echo "--------------------------------------------------" + + - name: Trigger build & send to FAD (override strict; else same->develop) + env: + GITLAB_HOST: mindbox.gitlab.yandexcloud.net + APP_PROJECT_ID: "900" + DEFAULT_APP_REF: develop + + SOURCE_BRANCH: ${{ inputs.branch }} + APP_REF_OVERRIDE: ${{ inputs.app_ref }} + + GITLAB_TRIGGER_TOKEN: ${{ secrets.GITLAB_TRIGGER_TOKEN }} + INPUT_COMMITS: ${{ env.commits }} + shell: bash + run: | + set -euo pipefail + + # Trim override so " " becomes empty + APP_REF_OVERRIDE="$(printf '%s' "${APP_REF_OVERRIDE:-}" | xargs)" + + # Normalize commits: + # - convert CRLF -> LF + # - if commits accidentally contain literal "\n", expand them to real newlines + normalize_commits() { + local raw="${1:-}" + # CRLF -> LF + raw="$(printf '%s' "$raw" | tr -d '\r')" + + # If it contains literal "\n" (backslash+n), expand escapes + if [[ "$raw" == *"\\n"* ]]; then + raw="$(printf '%b' "$raw")" + fi + + printf '%s' "$raw" + } + + COMMITS_TO_SEND="$(normalize_commits "${INPUT_COMMITS:-}")" + + echo "SDK branch (INPUT_BRANCH): $SOURCE_BRANCH" + echo "Manual App ref override: ${APP_REF_OVERRIDE:-}" + echo "Default App ref: $DEFAULT_APP_REF" + echo "" + echo "COMMITS_TO_SEND preview (cat -A):" + printf '%s' "$COMMITS_TO_SEND" | cat -A + echo "" + + trigger_pipeline() { + local ref="$1" + local tmp_body + tmp_body="$(mktemp)" + + local code + code="$(curl -sS -o "$tmp_body" -w '%{http_code}' --location \ + --retry 3 --retry-all-errors --retry-delay 2 \ + "https://${GITLAB_HOST}/api/v4/projects/${APP_PROJECT_ID}/trigger/pipeline" \ + --form "token=${GITLAB_TRIGGER_TOKEN}" \ + --form "ref=${ref}" \ + --form "variables[INPUT_BRANCH]=${SOURCE_BRANCH}" \ + --form "variables[INPUT_COMMITS]=${COMMITS_TO_SEND}")" + + local body + body="$(cat "$tmp_body" 2>/dev/null || true)" + rm -f "$tmp_body" + + echo "Trigger HTTP: $code (ref=$ref)" + echo "Response body:" + echo "$body" + + if [[ "$code" == "200" || "$code" == "201" ]]; then + local web_url + web_url="$( + printf '%s\n' "$body" | + grep -o '"web_url":"[^"]*"' | + head -n 1 | + cut -d'"' -f4 + )" + if [[ -n "${web_url:-}" ]]; then + echo "Pipeline URL: $web_url" + fi + return 0 + fi + + if [[ "$code" == "401" || "$code" == "403" ]]; then + echo "Auth error (HTTP $code). Check that GITLAB_TRIGGER_TOKEN is valid and has access to project ${APP_PROJECT_ID}." + return 1 + fi + + # Missing ref: GitLab returns 400 + "Reference not found" + if [[ "$code" == "400" || "$code" == "404" ]]; then + if [[ "$body" == *"Reference not found"* ]]; then + return 2 + fi + + echo "Got HTTP $code but it's NOT 'Reference not found'." + echo "This can happen if pipelines are blocked for triggers by workflow:rules or job rules when CI_PIPELINE_SOURCE == 'trigger'." + echo "Check the target repo .gitlab-ci.yml rules/workflow:rules." + return 1 + fi + + if [[ "$code" =~ ^5[0-9][0-9]$ ]]; then + echo "Server error (HTTP $code). GitLab/proxy might be temporarily unavailable." + return 1 + fi + + echo "Unexpected HTTP status: $code" + return 1 + } + + # If override is provided: try ONLY override; if missing ref -> fail + if [[ -n "$APP_REF_OVERRIDE" ]]; then + echo "Override provided -> trying ONLY App ref: $APP_REF_OVERRIDE" + trigger_pipeline "$APP_REF_OVERRIDE" || rc=$? + rc="${rc:-0}" + + if [[ "$rc" == "0" ]]; then + echo "Triggered on override ref." + exit 0 + fi + + if [[ "$rc" == "2" ]]; then + echo "ERROR: App ref not found: $APP_REF_OVERRIDE (GitLab returned 'Reference not found')" + exit 1 + fi + + echo "Trigger failed for reasons other than missing ref." + exit 1 + fi + + # No override: same branch -> fallback develop + desired_ref="$SOURCE_BRANCH" + fallback_ref="$DEFAULT_APP_REF" + + echo "No override -> trying App ref: $desired_ref" + trigger_pipeline "$desired_ref" || rc=$? + rc="${rc:-0}" + + if [[ "$rc" == "0" ]]; then + echo "Triggered on same branch." + exit 0 + fi + + if [[ "$rc" == "2" ]]; then + echo "Same branch not found. Falling back to: $fallback_ref" + trigger_pipeline "$fallback_ref" + echo "Triggered on fallback ref." + exit 0 + fi + + echo "Trigger failed for reasons other than missing ref." + exit 1