diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 367219adb..2d31fcd43 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,32 +1,10 @@ ## Description of Changes - - + ## Related Issue - - - -## Type of Change - -Please check the appropriate box that describes your PR: - -- [ ] 🐛 Bug Fix — Fixes a documented issue or incorrect behavior -- [ ] ✨ Content Enhancement — Updates or improves existing content -- [ ] ✍️ New Content — Adds new chapters, examples, or significant sections -- [ ] 🛠️ Other — Please describe in the *Description of Changes* section - - -## Additional Notes (Optional) - - - + ## Checklist diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c5bd8fb8f..0f9545847 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -13,7 +13,18 @@ updates: day: "monday" time: "09:00" - reviewers: - - "username" labels: - - "dependencies" + - "CI" + - "Dependencies" + + # Python dependencies + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "monthly" + day: "monday" + time: "09:00" + + labels: + - "Dependencies" + - "Python" \ No newline at end of file diff --git a/.github/mlc_config.json b/.github/mlc_config.json new file mode 100644 index 000000000..623ba463f --- /dev/null +++ b/.github/mlc_config.json @@ -0,0 +1,26 @@ +{ + "ignorePatterns": [ + { + "pattern": "^\\.git/" + }, + { + "pattern": "^http://localhost" + }, + { + "pattern": "^https://translatewiki\\.net" + } + ], + "httpHeaders": [ + { + "urls": ["^https?://"], + "headers": { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36" + } + } + ], + "timeout": "40s", + "retryOn429": true, + "aliveStatusCodes": [0, 200, 206, 403, 429], + "retryCount": 5, + "fallbackRetryDelay": "30s" +} \ No newline at end of file diff --git a/.github/workflows/auto_assign.yml b/.github/workflows/auto_assign.yml deleted file mode 100644 index eded0ca9a..000000000 --- a/.github/workflows/auto_assign.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Auto-assign Issue on First PR - -on: - pull_request: - types: [opened] - -jobs: - auto-assign: - runs-on: ubuntu-latest - - steps: - - name: Auto-assign issue to PR creator - uses: kentaro-m/auto-assign-action@v2.0.0 - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" - configuration: | - - addAssignees: - author: true # Add the PR author as assignee to the linked issue - - addReviewers: - author: false # Don't add reviewers to PRs - - skipIfAssigneesSet: true # Skip if issue already has assignees (ensures only first PR gets assigned) - - \ No newline at end of file diff --git a/.github/workflows/auto_comment.yml b/.github/workflows/auto_comment.yml new file mode 100644 index 000000000..c65dac1f4 --- /dev/null +++ b/.github/workflows/auto_comment.yml @@ -0,0 +1,112 @@ +name: Auto-comment on issues from PR + +on: + pull_request_target: + types: [opened, edited] + +permissions: + issues: write + pull-requests: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + comment-on-issue: + runs-on: ubuntu-latest + steps: + - name: Comment on and label linked issue + uses: actions/github-script@v7 + with: + token: ${{ secrets.GITHUB_TOKEN }} + script: | + const owner = context.repo.owner; + const repo = context.repo.repo; + const prNumber = context.payload.pull_request.number; + const prAuthor = context.payload.pull_request.user.login; + const prLink = context.payload.pull_request.html_url; + const prTitle = context.payload.pull_request.title || ''; + + const pattern = /(?:closes|fixes|resolves)\s+#(\d+)|#(\d+)/gi; + const issueNumbers = new Set(); + + const findIssues = (text) => { + if (!text) return; + for (const match of text.matchAll(pattern)) { + issueNumbers.add(match[1] || match[2]); + } + }; + + findIssues(context.payload.pull_request.body); + findIssues(prTitle); + + const { data: commits } = await github.rest.pulls.listCommits({ + owner, + repo, + pull_number: prNumber, + }); + + for (const commit of commits) { + findIssues(commit.commit.message); + } + + if (issueNumbers.size === 0) { + return; + } + + const ISSUE_PROCESSING_LIMIT = 10; + const issuesToProcess = Array.from(issueNumbers).slice(0, ISSUE_PROCESSING_LIMIT); + + for (const issueNumber of issuesToProcess) { + try { + let issue; + try { + const { data: issueData } = await github.rest.issues.get({ + owner, repo, issue_number: issueNumber, + }); + issue = issueData; + } catch (error) { + console.log(`Issue #${issueNumber} not found, skipping.`); + continue; + } + + if (issue.state !== 'open') { + console.log(`Issue #${issueNumber} is closed, skipping.`); + continue; + } + + const { data: comments } = await github.rest.issues.listComments({ + owner, repo, issue_number: issueNumber, + }); + + const botCommentIdentifier = "This issue has been claimed by"; + const alreadyCommented = comments.some(comment => comment.body && comment.body.includes(botCommentIdentifier)); + + if (alreadyCommented) { + continue; + } + + const commentBody = `**Issue Claimed**\n\nThis issue has been claimed by @${prAuthor} via pull request ${prLink}.\n\n**Note for other contributors:**\n\nTo avoid duplicate effort, please coordinate with the contributor or a project maintainer before submitting a new pull request for this issue.`; + + await github.rest.issues.createComment({ + owner, repo, issue_number: issueNumber, body: commentBody, + }); + + const labelToAdd = 'in progress'; + try { + await github.rest.issues.addLabels({ + owner, + repo, + issue_number: issueNumber, + labels: [labelToAdd] + }); + } catch (error) { + console.log(`Could not add label "${labelToAdd}" to issue #${issueNumber}.`); + } + + } catch (error) { + console.log(`Failed to process issue #${issueNumber}: ${error.message}`); + } + } + diff --git a/.github/workflows/checklink.yml b/.github/workflows/checklink.yml index 5478e5cd1..217364335 100644 --- a/.github/workflows/checklink.yml +++ b/.github/workflows/checklink.yml @@ -1,14 +1,22 @@ name: Check Markdown links -on: workflow_dispatch -# on: [pull_request] +on: + pull_request: + branches: [ "main" ] + schedule: + - cron: '0 0 1 * *' # Monthly + workflow_dispatch: jobs: markdown-link-check: + name: Check for broken links runs-on: ubuntu-latest steps: - - uses: actions/checkout@master - - uses: gaurav-nelson/github-action-markdown-link-check@v1 - with: - use-quiet-mode: 'yes' + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Run link checker + uses: gaurav-nelson/github-action-markdown-link-check@v1 + with: + config-file: '.github/mlc_config.json' use-verbose-mode: 'yes' diff --git a/.github/workflows/stale-pr.yml b/.github/workflows/stale-pr.yml index 2a0bc9139..e87fe504d 100644 --- a/.github/workflows/stale-pr.yml +++ b/.github/workflows/stale-pr.yml @@ -22,16 +22,27 @@ jobs: days-before-pr-stale: 30 days-before-pr-close: -1 - stale-pr-message: 'This pull request has been inactive for 30 days. It will be closed in 14 days if no further activity occurs.' + stale-pr-message: | + ⚠️ **Stale Pull Request Notice** + + This pull request has been automatically marked as stale because it has not had recent activity for 30 days. + + **Next Steps:** + - Add a comment to keep this PR active + - Push new commits to continue development + - Request review if ready for merge + - Close if no longer needed + + **Need Help?** Feel free to ask questions or request assistance from maintainers. + + Thank you for your contribution! stale-pr-label: '⌛ stale' - exempt-pr-labels: ✨ content enhancement,✍️ new content' + exempt-pr-labels: '✨ content enhancement,✍️ new content' exempt-draft-pr: true delete-branch: false only-pr-labels: '' # Process all PRs - operations-per-run: 30 enable-statistics: true - exempt-all-pr-milestones: true \ No newline at end of file diff --git a/DISCOVER/01_about.md b/DISCOVER/01_about.md index 8d0c67a4b..7afc5bd7c 100644 --- a/DISCOVER/01_about.md +++ b/DISCOVER/01_about.md @@ -13,7 +13,7 @@ It focuses specifically on plans, decisions, and actions organizers can take to _Funding to produce this cookbook was made possible by a generous grant from the_ **Moore Foundation** _._ **Further Reading:** -- [DISCOVER Cookbook Checklist](/13_inclusive-checklist.md) — A practical checklist for conference organizers to implement inclusive measures effectively. +- [DISCOVER Cookbook Checklist](13_inclusive-checklist.md) — A practical checklist for conference organizers to implement inclusive measures effectively. ## What this Cookbook Is Not diff --git a/DISCOVER/intro.md b/DISCOVER/intro.md index c29bcc969..fa0a134b8 100644 --- a/DISCOVER/intro.md +++ b/DISCOVER/intro.md @@ -9,7 +9,7 @@ The NumFOCUS DISCOVER Cookbook (Diverse & Inclusive Spaces and Conferences: Over This cookbook is intended as a resource for **organizers of conferences and events** to **support and encourage diversity and inclusion** at those events. This cookbook is **not** intended to provide **general instructions** on how to run a successful conference or event. -Read more about this cookbook [here](/01_about.md). +Read more about this cookbook [here](01_about.md). For a full statement of the NumFOCUS DISC Program mission and the NumFOCUS position on diversity and inclusion, please see [NumFOCUS Diversity and Inclusion Program](https://www.numfocus.org/programs/diversity-and-inclusion/). @@ -31,6 +31,6 @@ We also encourage you to do **at least one thing** in the "High Impact, Hig | **High Impact** | 🍎 Quick Wins | ✅ Do These | | **Low Impact** | 🗓️ Schedule (Chores) | 🛑 Stop Doing | -The "high impact, low effort" and "high impact, high effort" suggestions are summarized on the [Summary page](/02_minimal_measures.md). +The "high impact, low effort" and "high impact, high effort" suggestions are summarized on the [Summary page](02_minimal_measures.md). Please see the [NumFOCUS Privacy Policy](https://numfocus.org/privacy-policy) for more information about how we collect data.