プロジェクト

全般

プロフィール

タスク #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"'

いづ さん さんが6日前に更新 · 編集済み 操作 #1

DISCORD_WEBHOOK_URLのみ設定済み

エージェント ちゃん さんが6日前に更新 操作 #2

制作に着手しました。

  • ブランチ: feature/488
  • 対応方針: izu-IR の Discord 通知 CI を移植し、テスト不要のため no-op ジョブ + MR パイプライン向け notify:success / notify:failure.gitlab-ci.yml を新規構築する。

いづ さん さんが6日前に更新 操作 #3

  • ステータス未着手 から 実装中 に変更
  • 進捗率0 から 10 に変更

エージェント ちゃん さんが6日前に更新 操作 #4

  • ステータス実装中 から 完了 に変更
  • 進捗率10 から 100 に変更

対応が完了しました。

概要

mcp-world 用の .gitlab-ci.yml を新規作成。izu-IR の Discord 通知 CI を移植し、ビルド/テストを持たない本プロジェクト向けに整理した。MR パイプライン成功時に Discord へ通知を飛ばす。

変更点

  • .gitlab-ci.yml を新規追加(成果物)
  • ステージ: testno-op)/ notifynotify:success
  • no-op: echo のみで常に成功するテスト代替ジョブ(本プロジェクトにビルド/テストは無いため)
  • notify:success: merge_request_event パイプライン成功時に緑 embed を DISCORD_WEBHOOK_URL へ POST。allow_failure: true で通知失敗がマージゲートをブロックしない。Webhook 未設定時は no-op(exit 0)で素通り
  • workflow.rules で MR イベント + デフォルトブランチに限定し、重複パイプラインを抑止
  • 参考 YAML の notify:failure(on_failure)は意図的に省略。先行ジョブが echono-op のみで失敗し得ず on_failure が発火しないため(将来 fail し得る実ジョブを足す際に復活させる旨をコメントに明記)

確認

  • GitLab CI lint(validate_ci_lint)で valid: true(エラー/警告なし)。no-op / notify:success の2ジョブ・ステージ割当・allow_failure を確認
  • MR マージ済み

関連 MR

  • !2 (feature/488 → main)

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