プロジェクト

全般

プロフィール

タスク #488

完了

機能 #481: VRChatチルワールド制作 — 海沿い高層階の1LDK(二人向け)

GitLab CI構築

タスク #488: GitLab CI構築

いづ さん さんが6日前に追加. 6日前に更新.

ステータス:
完了
優先度:
通常
担当者:
対象バージョン:
開始日:
2026/06/30
期日:
進捗率:

100%

予定工数:

説明

以下を参考にDiscord通知を実装する。
多分このプロジェクトにテストは不要だと思うので、no-opジョブを必ず実行し、その後の通知を飛ばす。
もしテストが必要な場合はテストを追加。

# Discord notification for merge-request pipeline results (#306). Horizontally
# replicated from the izu-IR implementation (#305, the source ticket). Two terminal-stage
# jobs post the MR pipeline outcome to a Discord channel via an incoming webhook:
#   notify:success  -> green embed when every prior-stage job succeeded
#   notify:failure  -> red embed (with the list of failed jobs) when a prior job failed
# Both run ONLY on merge_request_event pipelines and never on the tag/release pipeline, and
# both allow_failure so a notification hiccup can never block the merge gate. The webhook
# URL is read from the masked CI/CD variable DISCORD_WEBHOOK_URL; when it is unset the jobs
# no-op (exit 0) so the pipeline still passes before the variable exists. Failed-job
# enrichment queries the GitLab API with the optional GITLAB_API_TOKEN (read_api) variable,
# falling back to CI_JOB_TOKEN; if neither can read the jobs endpoint the embed still links
# to the pipeline.
# NOTE: the project `default:` (Ubuntu temurin image + apt/sibling-repo before_script +
# gradle cache) is overridden here — these run on alpine with an apk before_script and an
# empty cache (mirroring the `release` / `no-op` jobs).
.notify-base:
  stage: notify
  image: alpine:3.20
  allow_failure: true
  before_script:
    - apk add --no-cache curl jq
  cache: {}

notify:success:
  extends: .notify-base
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      when: on_success
  script:
    - |
      if [ -z "$DISCORD_WEBHOOK_URL" ]; then
        echo "DISCORD_WEBHOOK_URL is not set; skipping Discord notification."
        exit 0
      fi
    - |
      jq -n \
        --arg title "✅ Pipeline succeeded" \
        --arg url "$CI_PIPELINE_URL" \
        --arg project "$CI_PROJECT_PATH" \
        --arg branch "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" \
        --arg target "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" \
        --arg mr "[!${CI_MERGE_REQUEST_IID}: ${CI_MERGE_REQUEST_TITLE}](${CI_MERGE_REQUEST_PROJECT_URL}/-/merge_requests/${CI_MERGE_REQUEST_IID})" \
        --arg commit "${CI_COMMIT_SHORT_SHA}: ${CI_COMMIT_TITLE}" \
        --arg author "$GITLAB_USER_NAME" \
        '{embeds: [{
            title: $title,
            url: $url,
            color: 3066993,
            fields: [
              {name: "Project", value: $project, inline: true},
              {name: "Branch", value: ($branch + " -> " + $target), inline: true},
              {name: "MR", value: $mr},
              {name: "Commit", value: $commit},
              {name: "Author", value: $author, inline: true}
            ]
          }]}' > payload.json
    - 'curl --fail --silent --show-error -H "Content-Type: application/json" -d @payload.json "$DISCORD_WEBHOOK_URL"'

notify:failure:
  extends: .notify-base
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      when: on_failure
  script:
    - |
      if [ -z "$DISCORD_WEBHOOK_URL" ]; then
        echo "DISCORD_WEBHOOK_URL is not set; skipping Discord notification."
        exit 0
      fi
    - |
      if [ -n "$GITLAB_API_TOKEN" ]; then
        AUTH_HEADER="PRIVATE-TOKEN: $GITLAB_API_TOKEN"
      else
        AUTH_HEADER="JOB-TOKEN: $CI_JOB_TOKEN"
      fi
      JOBS_JSON=$(curl --silent --show-error -H "$AUTH_HEADER" \
        "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/pipelines/${CI_PIPELINE_ID}/jobs?scope=failed&per_page=100" 2>/dev/null || echo "")
      FAILED_JOBS=""
      if echo "$JOBS_JSON" | jq -e 'type == "array"' >/dev/null 2>&1; then
        FAILED_JOBS=$(echo "$JOBS_JSON" | jq -r '[.[] | "- [" + .name + "](" + .web_url + ")"] | join("\n")')
      fi
      if [ -z "$FAILED_JOBS" ]; then
        FAILED_JOBS="(failed job list unavailable - open the pipeline for details)"
      fi
      # Discord embed field values cap at 1024 chars; truncate defensively.
      printf '%s' "$FAILED_JOBS" | cut -c1-1000 > failed_jobs.txt
    - |
      jq -n \
        --arg title "❌ Pipeline failed" \
        --arg url "$CI_PIPELINE_URL" \
        --arg project "$CI_PROJECT_PATH" \
        --arg branch "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" \
        --arg target "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" \
        --arg mr "[!${CI_MERGE_REQUEST_IID}: ${CI_MERGE_REQUEST_TITLE}](${CI_MERGE_REQUEST_PROJECT_URL}/-/merge_requests/${CI_MERGE_REQUEST_IID})" \
        --arg commit "${CI_COMMIT_SHORT_SHA}: ${CI_COMMIT_TITLE}" \
        --arg author "$GITLAB_USER_NAME" \
        --rawfile failed failed_jobs.txt \
        '{embeds: [{
            title: $title,
            url: $url,
            color: 15158332,
            fields: [
              {name: "Project", value: $project, inline: true},
              {name: "Branch", value: ($branch + " -> " + $target), inline: true},
              {name: "MR", value: $mr},
              {name: "Commit", value: $commit},
              {name: "Author", value: $author, inline: true},
              {name: "Failed jobs", value: $failed}
            ]
          }]}' > payload.json
    - 'curl --fail --silent --show-error -H "Content-Type: application/json" -d @payload.json "$DISCORD_WEBHOOK_URL"'

他の形式にエクスポート: PDF Atom