Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions .github/workflows/octo-pr-result-notify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ jobs:
import urllib.error

ALLOWED_KINDS = {
"pr_merged", "pr_closed", "pr_reopened",
"pr_merged", "pr_closed",
"review_approved", "review_changes_requested"
}

Expand Down Expand Up @@ -170,6 +170,7 @@ jobs:
pr_author = sanitize_text(require_env('PR_AUTHOR'), max_len=80)
event_kind = require_env("EVENT_KIND")
reviewer = sanitize_text(get_env('REVIEWER'), max_len=80)
reviewer_display = reviewer if reviewer else "(unknown)"
pr_additions = int(get_env("PR_ADDITIONS", "0") or "0")
pr_deletions = int(get_env("PR_DELETIONS", "0") or "0")
pr_changed_files = int(get_env("PR_CHANGED_FILES", "0") or "0")
Expand Down Expand Up @@ -199,22 +200,16 @@ jobs:
f"\U0001f464 {pr_author}\n"
f"\U0001f517 {pr_url}"
)
elif event_kind == "pr_reopened":
message = (
f"\U0001f504 [{repo_name}] PR #{pr_number} reopened · {pr_title}\n"
f"\U0001f464 {pr_author}\n"
f"\U0001f517 {pr_url}"
)
elif event_kind == "review_approved":
message = (
f"✅ [{repo_name}] PR #{pr_number} approved · {pr_title}\n"
f"\U0001f464 reviewer: {reviewer}\n"
f"\U0001f464 reviewer: {reviewer_display}\n"
f"\U0001f517 {pr_url}"
)
elif event_kind == "review_changes_requested":
message = (
f"\U0001f501 [{repo_name}] PR #{pr_number} changes requested · {pr_title}\n"
f"\U0001f464 reviewer: {reviewer}\n"
f"\U0001f464 reviewer: {reviewer_display}\n"
f"\U0001f517 {pr_url}"
)

Expand Down
21 changes: 6 additions & 15 deletions .github/workflows/octo-pr-review-feed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:
import urllib.request
import urllib.error

ALLOWED_ACTIONS = {"opened", "ready_for_review", "review_requested", "synchronize"}
ALLOWED_ACTIONS = {"ready_for_review", "review_requested"}

def require_env(name):
value = os.environ.get(name, "").strip()
Expand Down Expand Up @@ -156,25 +156,16 @@ jobs:
sys.exit(0)

emoji_map = {
"opened": "\U0001f535",
"ready_for_review": "✅",
"review_requested": "\U0001f440",
"synchronize": "\U0001f501",
}
emoji = emoji_map[event_action]

if event_action == "synchronize":
message = (
f"{emoji} [{repo_name}] PR #{pr_number} · {pr_title} — new commits pushed\n"
f"\U0001f464 {pr_author}\n"
f"\U0001f517 {pr_url}"
)
else:
message = (
f"{emoji} [{repo_name}] PR #{pr_number} · {pr_title}\n"
f"\U0001f464 {pr_author}\n"
f"\U0001f517 {pr_url}"
)
message = (
f"{emoji} [{repo_name}] PR #{pr_number} · {pr_title}\n"
f"\U0001f464 {pr_author}\n"
f"\U0001f517 {pr_url}"
)

failed = []
send_message(api_base_url, token, project_group_id, message, failed)
Expand Down
48 changes: 47 additions & 1 deletion .github/workflows/reusable-check-sprint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,13 @@
#
# on:
# pull_request_target:
# types: [opened, synchronize, reopened, edited]
# types: [opened, synchronize, reopened, edited, ready_for_review, converted_to_draft]
# # Include "edited" so the check re-runs when the PR description is
# # updated (e.g. developer adds "Closes #<issue>" after opening).
# # Include "ready_for_review" and "converted_to_draft" so the check
# # re-runs across draft↔ready transitions. REQUIRED for the draft-skip
# # to be safe: without "ready_for_review", a stale green from the draft
# # SHA persists after promotion to ready and bypasses the Sprint gate.
#
# jobs:
# check-sprint:
Expand Down Expand Up @@ -243,6 +247,48 @@ jobs:
return datetime.now(ZoneInfo("Asia/Shanghai")).date()


# --- Step 0: Skip draft PRs before any board-state queries ---------------
#
# This must run BEFORE Step 1 (sprint resolution) so draft PRs are never
# blocked by board-health failures (missing Sprint field, no active
# iteration, insufficient token scopes, etc.).
#
# NOTE: Callers must include `ready_for_review` in their pull_request_target
# types to ensure this check re-evaluates when a draft PR is marked ready
# for review. Without it, the green "skipped" result cached on the draft
# SHA will remain valid after the PR is promoted to ready, allowing it to
# merge without Sprint validation.
# See: https://github.com/Mininglamp-OSS/.github/pull/51

draft_data = graphql(
"""
query($owner: String!, $name: String!, $number: Int!) {
repository(owner: $owner, name: $name) {
pullRequest(number: $number) {
isDraft
}
}
}
""",
variables={"owner": REPO_OWNER, "name": REPO_SHORT, "number": PR_NUMBER},
)

try:
is_draft = draft_data["repository"]["pullRequest"]["isDraft"]
except (KeyError, TypeError) as e:
print(f"::error::Failed to read PR draft status for #{PR_NUMBER}. "
f"Detail: {e}")
sys.exit(1)

if is_draft:
print("✅ Skipping Sprint check for draft PR.")
print("::notice::Draft PR detected. Sprint check skipped (exit 0).")
print("::notice::REQUIRED caller config: include `ready_for_review` "
"in `pull_request_target.types`. Without it, this green "
"result is cached on the draft SHA and persists after the "
"PR is marked ready, bypassing the Sprint gate.")
sys.exit(0)

# --- Step 1: Determine the current sprint iteration -----------------------

try:
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/reusable-pr-contributor-welcome.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,15 @@ jobs:
}

const body = [
`Hey @${username}, thanks for your first contribution to Octo! 🎉`,
`Hey @${username}, thanks for your first PR to Octo! 🎉`,
'',
'Welcome to the community, and looking forward to more! 🐙',
'A maintainer will review it soon. While you wait, please make sure all CI checks pass.',
'',
'A few helpful links:',
'- 📖 [Contributing Guide](https://github.com/Mininglamp-OSS/.github/blob/main/CONTRIBUTING.md)',
'- 💬 [Discord Community](https://discord.gg/vj9Vsj9hSB)',
'',
'Welcome aboard! 🐙',
'— Octo Team',
].join('\n');

Expand Down