ci(actions): notify flow completion

This commit is contained in:
2026-07-08 18:12:06 +08:00
parent e686f6835c
commit b60ce37ab7
3 changed files with 75 additions and 41 deletions
+1 -2
View File
@@ -230,7 +230,6 @@ jobs:
if: always() if: always()
env: env:
ACTION_JOB_STATUS: ${{ job.status }} ACTION_JOB_STATUS: ${{ job.status }}
ACTION_NOTIFY_PROVIDER: ${{ secrets.ACTION_NOTIFY_PROVIDER }} FLOW_NOTIFY_BASE_URL: ${{ secrets.FLOW_NOTIFY_BASE_URL }}
ACTION_NOTIFY_WEBHOOK_URL: ${{ secrets.ACTION_NOTIFY_WEBHOOK_URL }}
run: | run: |
bash scripts/ci/notify-actions.sh bash scripts/ci/notify-actions.sh
+8
View File
@@ -0,0 +1,8 @@
curl -X POST https://flow.banlv-ai.com/requirements/REQ-XXXXXXXX/development-complete \
-H "Content-Type: application/json" \
-d '{
"operator": "gitea",
"result": "ready_for_test",
"summary": "Gitea 内容操作已完成:这里写他完成了什么、提交/分支/链接",
"source": "gitea"
}'
+66 -39
View File
@@ -5,22 +5,37 @@ warn() {
printf 'Notification warning: %s\n' "$*" >&2 printf 'Notification warning: %s\n' "$*" >&2
} }
provider="$(printf '%s' "${ACTION_NOTIFY_PROVIDER:-}" | tr '[:upper:]' '[:lower:]')" resolve_commit_message() {
webhook_url="${ACTION_NOTIFY_WEBHOOK_URL:-}" if [ -n "${ACTION_NOTIFY_COMMIT_MESSAGE:-}" ]; then
printf '%s\n' "$ACTION_NOTIFY_COMMIT_MESSAGE"
return 0
fi
if [ -z "$provider" ] || [ -z "$webhook_url" ]; then if command -v git >/dev/null 2>&1; then
echo "Action notification secrets are not configured, skip notification." git log -1 --pretty=%B 2>/dev/null || true
exit 0 fi
fi }
case "$provider" in extract_requirement_id() {
feishu | dingtalk) printf '%s\n' "$1" | grep -Eo 'REQ-[A-Za-z0-9_-]+' | head -n 1 || true
;; }
*)
warn "unsupported ACTION_NOTIFY_PROVIDER: $provider" normalize_job_result() {
exit 0 case "$1" in
;; success)
esac printf 'ready_for_test'
;;
cancelled | canceled)
printf 'cancelled'
;;
failure | failed)
printf 'failed'
;;
*)
printf 'failed'
;;
esac
}
branch_name="${BRANCH_NAME:-${GITHUB_REF_NAME:-}}" branch_name="${BRANCH_NAME:-${GITHUB_REF_NAME:-}}"
if [ -z "$branch_name" ] && [ -n "${GITHUB_REF:-}" ]; then if [ -z "$branch_name" ] && [ -n "${GITHUB_REF:-}" ]; then
@@ -38,11 +53,23 @@ if [ -z "$short_sha" ]; then
short_sha="unknown" short_sha="unknown"
fi fi
commit_message="$(resolve_commit_message)"
requirement_id="$(extract_requirement_id "$commit_message")"
if [ -z "$requirement_id" ]; then
warn "no REQ-* requirement id found in latest commit message, skip flow notification"
exit 0
fi
base_url="${FLOW_NOTIFY_BASE_URL:-https://flow.banlv-ai.com}"
base_url="${base_url%/}"
notify_url="$base_url/requirements/$requirement_id/development-complete"
deploy_env="${DEPLOY_ENV:-unknown}" deploy_env="${DEPLOY_ENV:-unknown}"
image_tag="${IMAGE_VERSION_TAG:-unknown}" image_tag="${IMAGE_VERSION_TAG:-unknown}"
job_status="${ACTION_JOB_STATUS:-unknown}" job_status="${ACTION_JOB_STATUS:-unknown}"
workflow_name="${GITHUB_WORKFLOW:-Docker Image}" workflow_name="${GITHUB_WORKFLOW:-Docker Image}"
repository="${GITHUB_REPOSITORY:-cozsweet-frontend-nextjs}" repository="${GITHUB_REPOSITORY:-cozsweet-frontend-nextjs}"
result="$(normalize_job_result "$job_status")"
run_url="" run_url=""
if [ -n "${GITHUB_SERVER_URL:-}" ] && [ -n "${GITHUB_REPOSITORY:-}" ] && [ -n "${GITHUB_RUN_ID:-}" ]; then if [ -n "${GITHUB_SERVER_URL:-}" ] && [ -n "${GITHUB_REPOSITORY:-}" ] && [ -n "${GITHUB_RUN_ID:-}" ]; then
@@ -52,9 +79,11 @@ if [ -z "$run_url" ]; then
run_url="${GITHUB_SERVER_URL:-unknown}" run_url="${GITHUB_SERVER_URL:-unknown}"
fi fi
export ACTION_NOTIFY_PROVIDER="$provider" export FLOW_NOTIFY_OPERATOR="gitea"
export ACTION_NOTIFY_MESSAGE="$(cat <<EOF export FLOW_NOTIFY_SOURCE="gitea"
cozsweet Actions finished export FLOW_NOTIFY_RESULT="$result"
export FLOW_NOTIFY_SUMMARY="$(cat <<EOF
Gitea workflow finished.
Workflow: $workflow_name Workflow: $workflow_name
Repository: $repository Repository: $repository
@@ -62,37 +91,35 @@ Branch: $branch_name
Environment: $deploy_env Environment: $deploy_env
Commit: $short_sha Commit: $short_sha
Image: $image_tag Image: $image_tag
Result: $job_status Status: $job_status
Run: $run_url Run: $run_url
EOF EOF
)" )"
payload="$(node <<'NODE' payload="$(node <<'NODE'
const provider = process.env.ACTION_NOTIFY_PROVIDER; const payload = {
const message = process.env.ACTION_NOTIFY_MESSAGE; operator: process.env.FLOW_NOTIFY_OPERATOR,
result: process.env.FLOW_NOTIFY_RESULT,
summary: process.env.FLOW_NOTIFY_SUMMARY,
source: process.env.FLOW_NOTIFY_SOURCE,
};
if (provider === "feishu") { process.stdout.write(JSON.stringify(payload));
process.stdout.write(JSON.stringify({
msg_type: "text",
content: { text: message },
}));
} else if (provider === "dingtalk") {
process.stdout.write(JSON.stringify({
msgtype: "text",
text: { content: message },
}));
} else {
process.exit(1);
}
NODE NODE
)" )"
if ! curl -fsS \ if [ "${FLOW_NOTIFY_DRY_RUN:-}" = "1" ]; then
-H "Content-Type: application/json" \ printf 'Flow notification dry run URL: %s\n' "$notify_url"
-d "$payload" \ printf 'Flow notification dry run payload: %s\n' "$payload"
"$webhook_url" >/dev/null; then
warn "failed to send $provider notification"
exit 0 exit 0
fi fi
echo "Sent $provider action notification." if ! curl -fsS \
-X POST "$notify_url" \
-H "Content-Type: application/json" \
-d "$payload" >/dev/null; then
warn "failed to send flow notification for $requirement_id"
exit 0
fi
echo "Sent flow notification for $requirement_id."