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
11 changes: 11 additions & 0 deletions .github/mergeable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ mergeable:
must_include:
regex: "^(bug|enhancement|documentation|feature|refactor|performance|chore|wip|test|ci|security|dependencies)$"
message: "PR must include at least one valid label."
# Ensure PR has at least one assignee

- do: assignee
min:
count: 1
message: "PR must have at least one assignee."
# Ensure PR has at least one reviewer requested
- do: approvals
min:
count: 1
message: "PR must have at least one reviewer requested or approved."

pass:
- do: labels
Expand Down
178 changes: 178 additions & 0 deletions .github/workflows/github-event-notification.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
name: Notify (GitHub Events)

permissions:
issues: write
pull-requests: write
contents: read

on:
issues:
types: [opened, edited, reopened, closed, assigned, labeled]
pull_request:
types: [opened, closed, reopened, ready_for_review, review_requested]
pull_request_review:
types: [submitted, edited, dismissed]
issue_comment:
types: [created, edited]
pull_request_review_comment:
types: [created, edited]

jobs:
notify:
runs-on: ubuntu-latest
name: Send Notifications

steps:
- name: Determine Event Type
id: event_info
run: |
EVENT="${{ github.event_name }}"
ACTION="${{ github.event.action }}"
REPO="${{ github.repository }}"
ACTOR="${{ github.actor }}"
REPO_URL="${{ github.server_url }}/${{ github.repository }}"

if [[ "$EVENT" == "issues" ]]; then
TITLE="Issue $ACTION: ${{ github.event.issue.title }}"
URL="${{ github.event.issue.html_url }}"
NUMBER="${{ github.event.issue.number }}"
USER="${{ github.event.issue.user.login }}"
DESCRIPTION="Issue #$NUMBER by $USER"
STATE="${{ github.event.issue.state }}"
EMOJI="🐛"

elif [[ "$EVENT" == "pull_request" ]]; then
NUMBER="${{ github.event.pull_request.number }}"
USER="${{ github.event.pull_request.user.login }}"
URL="${{ github.event.pull_request.html_url }}"
STATE="${{ github.event.pull_request.state }}"
SOURCE="${{ github.event.pull_request.head.ref }}"
TARGET="${{ github.event.pull_request.base.ref }}"

if [[ "$ACTION" == "closed" && "${{ github.event.pull_request.merged }}" == "true" ]]; then
TITLE="PR merged: ${{ github.event.pull_request.title }}"
EMOJI="✅"
STATE="merged"
elif [[ "$ACTION" == "closed" ]]; then
TITLE="PR closed: ${{ github.event.pull_request.title }}"
EMOJI="❌"
else
TITLE="PR $ACTION: ${{ github.event.pull_request.title }}"
EMOJI="🔀"
fi
DESCRIPTION="PR #$NUMBER by $USER: $SOURCE → $TARGET"

elif [[ "$EVENT" == "pull_request_review" ]]; then
TITLE="PR Review: ${{ github.event.pull_request.title }}"
URL="${{ github.event.review.html_url }}"
NUMBER="${{ github.event.pull_request.number }}"
USER="${{ github.event.review.user.login }}"
REVIEW_STATE="${{ github.event.review.state }}"
STATE="${{ github.event.review.state }}"
SOURCE="${{ github.event.pull_request.head.ref }}"
TARGET="${{ github.event.pull_request.base.ref }}"
DESCRIPTION="Review by $USER on PR #$NUMBER"
EMOJI="👀"

elif [[ "$EVENT" == "issue_comment" ]]; then
NUMBER="${{ github.event.issue.number }}"
USER="${{ github.event.comment.user.login }}"
URL="${{ github.event.comment.html_url }}"
STATE="commented"

if [[ "${{ github.event.issue.pull_request }}" != "" ]]; then
TITLE="Comment on PR: ${{ github.event.issue.title }}"
EMOJI="💬"
else
TITLE="Comment on Issue: ${{ github.event.issue.title }}"
EMOJI="💬"
fi
DESCRIPTION="Comment by $USER on #$NUMBER"

elif [[ "$EVENT" == "pull_request_review_comment" ]]; then
TITLE="Comment on PR: ${{ github.event.pull_request.title }}"
URL="${{ github.event.comment.html_url }}"
NUMBER="${{ github.event.pull_request.number }}"
USER="${{ github.event.comment.user.login }}"
STATE="commented"
SOURCE="${{ github.event.pull_request.head.ref }}"
TARGET="${{ github.event.pull_request.base.ref }}"
DESCRIPTION="Review comment by $USER on PR #$NUMBER"
EMOJI="💬"
else
TITLE="GitHub Event: $EVENT"
URL="${{ github.event.repository.html_url }}"
DESCRIPTION="Event triggered in $REPO"
STATE="N/A"
NUMBER="N/A"
USER="$ACTOR"
EMOJI="📢"
fi

echo "title=$TITLE" >> $GITHUB_OUTPUT
echo "url=$URL" >> $GITHUB_OUTPUT
echo "description=$DESCRIPTION" >> $GITHUB_OUTPUT
echo "emoji=$EMOJI" >> $GITHUB_OUTPUT
echo "number=${NUMBER:-N/A}" >> $GITHUB_OUTPUT
echo "user=${USER:-$ACTOR}" >> $GITHUB_OUTPUT
echo "state=${STATE:-N/A}" >> $GITHUB_OUTPUT
echo "source=${SOURCE:-N/A}" >> $GITHUB_OUTPUT
echo "target=${TARGET:-N/A}" >> $GITHUB_OUTPUT
echo "repo_url=$REPO_URL" >> $GITHUB_OUTPUT

- name: Google Chat Notification
if: always()
uses: Co-qn/google-chat-notification@releases/v1
with:
name: ${{ steps.event_info.outputs.title }}
url: ${{ secrets.GOOGLE_CHAT_WEBHOOK }}
status: ${{ job.status }}

- name: Slack Notification
if: always()
uses: slackapi/slack-github-action@v1.24.0
with:
channel-id: ${{ secrets.SLACK_CHANNEL_ID }}
payload: |
{
"text": "${{ steps.event_info.outputs.title }}",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "${{ steps.event_info.outputs.emoji }} ${{ steps.event_info.outputs.title }}"
}
},
{
"type": "section",
"fields": [
{ "type": "mrkdwn", "text": "*Repository:*\n<${{ steps.event_info.outputs.repo_url }}|${{ github.repository }}>" },
{ "type": "mrkdwn", "text": "*Event:*\n${{ github.event_name }}" },
{ "type": "mrkdwn", "text": "*Author:*\n${{ steps.event_info.outputs.user }}" },
{ "type": "mrkdwn", "text": "*Action:*\n${{ github.event.action }}" },
{ "type": "mrkdwn", "text": "*Number:*\n<${{ steps.event_info.outputs.url }}|#${{ steps.event_info.outputs.number }}>" },
{ "type": "mrkdwn", "text": "*State:*\n${{ steps.event_info.outputs.state }}" }
]
},
{
"type": "section",
"text": { "type": "mrkdwn", "text": "${{ steps.event_info.outputs.description }}" }
},
{
"type": "actions",
"elements": [
{ "type": "button", "text": { "type": "plain_text", "text": "View on GitHub" }, "url": "${{ steps.event_info.outputs.url }}", "style": "primary" },
{ "type": "button", "text": { "type": "plain_text", "text": "View Repository" }, "url": "${{ steps.event_info.outputs.repo_url }}" }
]
},
{
"type": "context",
"elements": [
{ "type": "mrkdwn", "text": "Triggered by ${{ github.actor }} • ${{ github.event_name }} event" }
]
}
]
}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
47 changes: 47 additions & 0 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Schedule Stale PRs and Issues Management

permissions:
actions: write
contents: write
issues: write
pull-requests: write

on:
schedule:
- cron: '0 9 * * 1,4' # Monday & Thursday at 9 AM UTC
workflow_dispatch:

concurrency:
group: stale-management
cancel-in-progress: false

jobs:
stale-management:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Manage Stale Issues and PRs
uses: actions/stale@v10.1.0
with:
repo-token: ${{ github.token }}

# General settings
days-before-stale: '30'
days-before-close: '7'
operations-per-run: '60'
remove-stale-when-updated: 'true'

# Issue-specific settings
stale-issue-label: 'stale'
stale-issue-message: 'This issue has been marked as stale due to inactivity. It will be closed in 7 days unless there is further activity.'
close-issue-message: 'This issue has been closed due to inactivity. Please feel free to reopen if you think it is still relevant.'
exempt-issue-labels: 'bug,critical,security,high-priority,enhancement,discussion,help wanted,good first issue'

# PR-specific settings
stale-pr-label: 'stale'
stale-pr-message: 'This pull request has been marked as stale due to inactivity. It will be closed in 7 days unless further changes are made or a review is requested.'
close-pr-message: 'This pull request has been closed due to inactivity. Please feel free to reopen if you think it is still relevant.'
exempt-pr-labels: 'WIP,In Progress'
1 change: 1 addition & 0 deletions cluster-api/schemas/cluster_schema.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# pylint: disable=import-error
"""
Utility functions for cluster operations.

Expand Down