From 78414afbb73e6bb25e1b0d5f6a6d8ef675427dac Mon Sep 17 00:00:00 2001 From: rajivbb Date: Tue, 2 Dec 2025 13:47:44 +0545 Subject: [PATCH 1/4] feat: add probot app and noitification workflow --- .github/mergeable.yml | 45 +++++++++++++++++++ .../workflows/github-event-notification.yaml | 28 ++++++++++++ .github/workflows/pre-commit.yaml | 19 ++++++++ .github/workflows/stale.yml | 38 ++++++++++++++++ 4 files changed, 130 insertions(+) create mode 100644 .github/mergeable.yml create mode 100644 .github/workflows/github-event-notification.yaml create mode 100644 .github/workflows/pre-commit.yaml create mode 100644 .github/workflows/stale.yml diff --git a/.github/mergeable.yml b/.github/mergeable.yml new file mode 100644 index 0000000..80971cd --- /dev/null +++ b/.github/mergeable.yml @@ -0,0 +1,45 @@ +version: 2 +mergeable: + - when: pull_request.*, pull_request_review.* + validate: + # Validate PR title + - do: title + must_include: + regex: '^(feat|docs|chore|fix|refactor|test|style|perf)(\(\w+\))?: .{5,}' + message: "Semantic release conventions must be followed. Example: feat(auth): add login page. Title must be at least 5 characters after the prefix." + + # Ensure PR description is provided + - do: description + must_include: + regex: "[\\s\\S]{20,}" # At least 20 characters + message: "Please provide a meaningful description of the PR (minimum 20 characters)." + + # Ensure PR references an associated issue + - do: description + must_include: + regex: "(Closes|Fixes|Resolves|Addresses)\\s+#[0-9]+(,?\\s*#[0-9]+)*" + message: "PR must reference at least one issue (e.g., Closes #123, Fixes #123, #124)." + + # Ensure at least one required label is applied + - do: label + 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 + add: + - "validated" + - do: checks + status: "success" diff --git a/.github/workflows/github-event-notification.yaml b/.github/workflows/github-event-notification.yaml new file mode 100644 index 0000000..4f00f4e --- /dev/null +++ b/.github/workflows/github-event-notification.yaml @@ -0,0 +1,28 @@ +name: 5. Notification (Github-Event) + + +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: + uses: berrybytes/actions/.github/workflows/notifications.yaml@main + secrets: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + GOOGLE_CHAT_WEBHOOK: ${{ secrets.GOOGLE_CHAT_WEBHOOK }} diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml new file mode 100644 index 0000000..dca229d --- /dev/null +++ b/.github/workflows/pre-commit.yaml @@ -0,0 +1,19 @@ +name: 6. Pre-Commit Check + +on: + push: + branches: + - main + - develop + - 'feat/**' + - 'feature/**' + - 'test/**' + - 'chore/**' + - 'fix/**' + - 'hotfix/**' + - 'docs/**' + pull_request: + types: [opened, synchronize, reopened] +jobs: + pre-commit-check: + uses: berrybytes/actions/.github/workflows/pre-commit.yaml@main diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..a912507 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,38 @@ +name: 7. Schedule Stale PRs and Issues Management + +on: + schedule: + - cron: '0 9 * * 1,4' # Monday & Thursday at 9 AM UTC + workflow_dispatch: + +concurrency: + group: stale-management + cancel-in-progress: false + +jobs: + call-stale-management: + permissions: + actions: write + contents: write + issues: write + pull-requests: write + + uses: berrybytes/actions/.github/workflows/stale.yaml@main + with: + # General settings (apply to both issues and PRs) + days-before-stale: '30' + days-before-close: '7' + operations-per-run: '60' + remove-stale-when-updated: 'true' + + # 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' + + # 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' From b6b87fff41c3044b21f5ffd732462284fac503d3 Mon Sep 17 00:00:00 2001 From: rajivbb Date: Tue, 2 Dec 2025 13:49:08 +0545 Subject: [PATCH 2/4] feat: add probot app and noitification workflow --- .prettierrc | 22 ++++++++++++++++++++++ .stylelintrc.json | 9 +++++++++ commitlint.config.cjs | 24 ++++++++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 .prettierrc create mode 100644 .stylelintrc.json create mode 100644 commitlint.config.cjs diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..5902ac3 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,22 @@ +{ + "singleQuote": true, + "trailingComma": "es5", + "tabWidth": 2, + "semi": true, + "printWidth": 100, + "overrides": [ + { + "files": "*.html", + "options": { + "parser": "html" + } + }, + { + "files": "*.css", + "options": { + "parser": "css" + } + } + ], + "ignore": ["node_modules"] +} diff --git a/.stylelintrc.json b/.stylelintrc.json new file mode 100644 index 0000000..76c0117 --- /dev/null +++ b/.stylelintrc.json @@ -0,0 +1,9 @@ +{ + "extends": "stylelint-config-standard", + "rules": { + "no-duplicate-selectors": true, + "color-hex-length": "short", + "selector-max-id": 0, + "selector-no-qualifying-type": true + } +} diff --git a/commitlint.config.cjs b/commitlint.config.cjs new file mode 100644 index 0000000..a0e89b0 --- /dev/null +++ b/commitlint.config.cjs @@ -0,0 +1,24 @@ +module.exports = { + extends: ['@commitlint/config-conventional'], + rules: { + 'type-enum': [2, 'always', [ + 'feat', // A new feature + 'fix', // A bug fix + 'docs', // Documentation only changes + 'style', // Changes that do not affect code meaning + 'refactor', // A code change that neither fixes a bug nor adds a feature + 'perf', // A code change that improves performance + 'test', // Adding missing tests or correcting existing tests + 'build', // Build system or external dependencies + 'ci', // CI configuration changes + 'chore', // Other changes that don't modify src or test files + 'revert', // Reverts a previous commit + ]], + 'type-case': [2, 'always', 'lowerCase'], + 'type-empty': [2, 'never'], + 'scope-case': [2, 'always', 'lowerCase'], + 'subject-empty': [2, 'never'], + 'subject-full-stop': [2, 'never', '.'], + 'header-max-length': [2, 'always', 72], + }, +}; From abe0c80ff81f6bc8e39b083fb949a99c4e6da130 Mon Sep 17 00:00:00 2001 From: rajivbb Date: Tue, 2 Dec 2025 17:10:29 +0545 Subject: [PATCH 3/4] chore: workflow update --- .../workflows/github-event-notification.yaml | 166 +++++++++++++++++- .github/workflows/pre-commit.yaml | 103 ++++++++++- .github/workflows/stale.yml | 63 ++++--- 3 files changed, 294 insertions(+), 38 deletions(-) diff --git a/.github/workflows/github-event-notification.yaml b/.github/workflows/github-event-notification.yaml index 4f00f4e..d452f56 100644 --- a/.github/workflows/github-event-notification.yaml +++ b/.github/workflows/github-event-notification.yaml @@ -1,12 +1,10 @@ -name: 5. Notification (Github-Event) - +name: Notify (GitHub Events) permissions: issues: write pull-requests: write contents: read - on: issues: types: [opened, edited, reopened, closed, assigned, labeled] @@ -21,8 +19,160 @@ on: jobs: notify: - uses: berrybytes/actions/.github/workflows/notifications.yaml@main - secrets: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} - GOOGLE_CHAT_WEBHOOK: ${{ secrets.GOOGLE_CHAT_WEBHOOK }} + 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 }} diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml index dca229d..75e8b3d 100644 --- a/.github/workflows/pre-commit.yaml +++ b/.github/workflows/pre-commit.yaml @@ -1,4 +1,4 @@ -name: 6. Pre-Commit Check +name: Pre-Commit Checks on: push: @@ -14,6 +14,103 @@ on: - 'docs/**' pull_request: types: [opened, synchronize, reopened] + jobs: - pre-commit-check: - uses: berrybytes/actions/.github/workflows/pre-commit.yaml@main + precommit: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install pre-commit + run: | + python -m pip install --upgrade pip + pip install pre-commit + + - name: Load Pre-commit Config + run: | + if [ ! -f ".pre-commit-config.yaml" ]; then + echo " No .pre-commit-config.yaml found — downloading BerryBytes global config..." + curl -sSL \ + https://raw.githubusercontent.com/BerryBytes/precommit-util/main/global/precommitFile/.pre-commit-config.yaml \ + -o .pre-commit-config.yaml + else + echo "✔ Using project's existing .pre-commit-config.yaml" + fi + + - name: Inject temporary Stylelint config for CI + run: | + if [ ! -f ".stylelintrc.json" ]; then + echo " Creating temporary .stylelintrc.json for CI..." + cat < .stylelintrc.json + { + "extends": "stylelint-config-standard", + "rules": { + "no-duplicate-selectors": true, + "color-hex-length": "short", + "selector-no-qualifying-type": true, + "selector-max-id": 0 + } + } + EOF + else + echo "✔ .stylelintrc.json already exists — skipping" + fi + + # -------------------------------------------------------------------- + # STEP 1: Run pre-commit (capture full logs and exit code safely) + # -------------------------------------------------------------------- + - name: Run pre-commit (full logs) + id: runprecommit + run: | + echo "🔍 Running full pre-commit checks..." + + set +e # allow failure + pre-commit run --all-files --verbose --show-diff-on-failure --color never \ + | tee full_precommit.log + exit_code=${PIPESTATUS[0]} + + echo "Pre-commit exit code: $exit_code" + echo "$exit_code" > precommit_exit_code.txt + + # -------------------------------------------------------------------- + # STEP 2: Summary of FAILED hooks + # -------------------------------------------------------------------- + - name: Pre-commit summary of failed hooks + run: | + echo "=====================================================" + echo " PRE-COMMIT SUMMARY" + echo "=====================================================" + + exit_code=$(cat precommit_exit_code.txt) + + if [ "$exit_code" = "0" ]; then + echo " All hooks passed!" + exit 0 + fi + + echo " Hooks failed — showing summary:" + echo "" + + echo " FAILED HOOKS:" + grep -E "^\w.*\.{3,}Failed" full_precommit.log || echo " None" + echo "-----------------------------------------------------" + + echo " FILES WITH ISSUES:" + grep -E "files were modified by this hook" -A3 full_precommit.log \ + | sed 's/^/ - /' || echo " None" + echo "-----------------------------------------------------" + + echo " ERROR DETAILS:" + grep -Ei "(error|failed|violation|missing|line too long|could not|warning)" full_precommit.log \ + | grep -Ev "^(---|\+\+\+|@@|diff --git|index )" \ + | sed 's/^/ • /' || echo " None" + echo "-----------------------------------------------------" + + exit $exit_code diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index a912507..e0e34a5 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -1,4 +1,10 @@ -name: 7. Schedule Stale PRs and Issues Management +name: Schedule Stale PRs and Issues Management + +permissions: + actions: write + contents: write + issues: write + pull-requests: write on: schedule: @@ -10,29 +16,32 @@ concurrency: cancel-in-progress: false jobs: - call-stale-management: - permissions: - actions: write - contents: write - issues: write - pull-requests: write - - uses: berrybytes/actions/.github/workflows/stale.yaml@main - with: - # General settings (apply to both issues and PRs) - days-before-stale: '30' - days-before-close: '7' - operations-per-run: '60' - remove-stale-when-updated: 'true' - - # 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' - - # 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' + 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' From 0475294ebf180e0b2a2d54e19e0f308b3a97250a Mon Sep 17 00:00:00 2001 From: rajivbb Date: Tue, 2 Dec 2025 17:49:52 +0545 Subject: [PATCH 4/4] chore: workflow update for goimport error --- .github/workflows/pre-commit.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml index 75e8b3d..f016380 100644 --- a/.github/workflows/pre-commit.yaml +++ b/.github/workflows/pre-commit.yaml @@ -23,6 +23,16 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.22.0' + + - name: Install goimports + run: | + go install golang.org/x/tools/cmd/goimports@latest + echo "$HOME/go/bin" >> $GITHUB_PATH + - name: Set up Python uses: actions/setup-python@v5 with: