diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 00000000..d4ab8ff3 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,82 @@ +# GitHub Copilot Instructions for voc4cat + +This repository contains a SKOS vocabulary for catalysis. When reviewing pull requests, please help contributors follow these best practices: + +## Common PR Submission Issues + +### Missing Classification Under Top Concepts + +**Problem:** New concepts in the SKOS vocabulary must be properly classified by linking them to the hierarchy through `skos:broader` relationships, eventually reaching one of the top concepts. + +**What to look for:** +- Excel files in `inbox-excel-vocabs/` with new concepts +- Check if new concepts have `skos:broader` relationships defined +- Verify the broader concepts eventually chain to a top concept like: + - Process + - Method + - Material entity + - Quality + - Role + - etc. + +**Suggested response:** +``` +I noticed some new concepts in your submission. Please ensure each new concept has: + +1. A `skos:broader` relationship to a parent concept +2. A chain of broader relationships that eventually reaches one of the top-level concepts + +This ensures proper integration into the vocabulary hierarchy. You can check the existing vocabulary structure at https://nfdi4cat.github.io/voc4cat/ for examples. + +Let me know if you need help identifying the appropriate parent concepts! +``` + +## General Guidance + +### What Makes a Good Contribution + +- **Small, focused changes**: Single concept additions or small groups (~20 concepts) +- **Clear descriptions**: Explain what the concepts represent and why they're needed +- **Proper classification**: All concepts linked into the hierarchy +- **Use Excel workflow**: Never edit .ttl files directly, only the Excel template +- **Request ID ranges**: Get an ID range before adding new concepts + +### What to Check in PRs + +1. **File locations**: Excel files must be in `inbox-excel-vocabs/` +2. **File naming**: Keep as `voc4cat.xlsx` +3. **No direct .ttl edits**: Turtle files should only be modified by CI +4. **Documentation**: Changes should be described in PR description +5. **Size**: Large contributions should be split into smaller PRs + +### Helpful Resources + +- Contributing Guide: https://github.com/nfdi4cat/voc4cat/blob/main/docs/docs_usage/how-to-contribute.md +- Vocabulary Guidelines: https://github.com/nfdi4cat/voc4cat/blob/main/docs/docs_usage/guidelines.md +- Current Vocabulary as HTML: https://nfdi4cat.github.io/voc4cat/dev/voc4cat/index.html +- Current Vocabulary in SKOS/turtle format: https://github.com/nfdi4cat/voc4cat/tree/main/vocabularies/voc4cat + +## Tone and Approach + +- Be welcoming and encouraging, especially to first-time contributors +- Explain **why** something is important, not just that it's required +- Provide concrete, actionable steps to fix issues +- Acknowledge that GitHub's limitations (like org forks) aren't the contributor's fault +- Offer to help if contributors have questions + +## What NOT to Do + +- Don't block PRs unnecessarily - some issues can be fixed post-merge +- Don't be overly verbose - keep feedback concise and actionable +- Don't criticize the contributor - focus on the code/process +- Don't request changes for minor style issues in definitions +- Don't duplicate feedback if it's already been mentioned + +## Priority Order + +1. **Critical**: Organization account issues (blocks CI) +2. **Important**: Missing classification (affects vocabulary quality) +3. **Helpful**: Main branch usage (improves contributor workflow) +4. **Nice-to-have**: Documentation improvements, minor formatting + +Focus feedback on critical and important issues first. Mention helpful suggestions but don't insist on them for small contributions. diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml new file mode 100644 index 00000000..97c4a7e0 --- /dev/null +++ b/.github/workflows/pr-checks.yml @@ -0,0 +1,165 @@ +# This workflow checks for common PR submission issues and provides helpful feedback +# - PRs from fork's main branch (helpful workflow suggestion) +# - Organization account submissions (critical - blocks CI due to GitHub limitation) +# +# Security Note: This workflow uses pull_request_target which runs in the context +# of the base repository, not the fork. User-controlled data (PR titles, descriptions, +# branch names, usernames) must be sanitized before use to prevent script injection. + +name: PR Submission Checks + +on: + pull_request_target: + types: [opened, reopened, synchronize] + branches: + - main + +permissions: + pull-requests: write + contents: read + +jobs: + check-pr-submission: + name: Check PR submission best practices + runs-on: ubuntu-latest + + steps: + - name: Check if PR is from main branch of fork + id: check-main-branch + uses: actions/github-script@v7 + with: + script: | + const pr = context.payload.pull_request; + + // Get PR details from context (these are all user-controlled) + const headRef = pr.head.ref; + const headRepo = pr.head.repo.full_name; + const baseRepo = pr.base.repo.full_name; + const isFork = headRepo !== baseRepo; + const isFromMain = headRef === 'main'; + const isFromOrg = pr.head.repo.owner.type === 'Organization'; + + // Log details - no user input in template literals for security + console.log('PR number:', pr.number); + console.log('Head branch:', headRef); + console.log('Head repo:', headRepo); + console.log('Base repo:', baseRepo); + console.log('Is fork:', isFork); + console.log('From main branch:', isFromMain); + console.log('Owner type:', pr.head.repo.owner.type); + + core.setOutput('is_fork', isFork); + core.setOutput('is_from_main', isFromMain); + core.setOutput('is_from_org', isFromOrg); + core.setOutput('head_ref', headRef); + core.setOutput('head_repo', headRepo); + + return { + isFork, + isFromMain, + isFromOrg, + needsComment: isFork && isFromMain + }; + + - name: Post comment about main branch submission + if: steps.check-main-branch.outputs.is_fork == 'true' && steps.check-main-branch.outputs.is_from_main == 'true' + uses: actions/github-script@v7 + with: + script: | + const pr = context.payload.pull_request; + + // Check if we already posted this comment + const comments = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number + }); + + const botComment = comments.data.find(comment => + comment.user.type === 'Bot' && + comment.body.includes('submitted from the main branch') + ); + + if (botComment) { + console.log('Comment about main branch already exists, skipping'); + return; + } + + // Sanitize username - GitHub usernames can only contain alphanumeric characters and hyphens + const username = pr.user.login.replace(/[^a-zA-Z0-9-]/g, ''); + + // Post helpful comment + const commentBody = `Hi @${username}! 👋 + +Thank you for your contribution to voc4cat! + +⚠️ We noticed that this pull request was submitted from the \`main\` branch of your fork. +While this works, it can cause issues + +- It makes it harder to keep your fork updated with upstream changes +- You won't be able to work on multiple PRs at once +- Future contributions may be complicated by merge conflicts + +This PR can still be merged, but please use feature branches going forward! + +For more information, see our [How to contribute](https://nfdi4cat.github.io/voc4cat/docs_usage/how-to-contribute.html) guide. + +*If you have any questions, please don't hesitate to ask!* 🚀`; + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body: commentBody + }); + + - name: Post info about organization account + if: steps.check-main-branch.outputs.is_from_org == 'true' + uses: actions/github-script@v7 + with: + script: | + const pr = context.payload.pull_request; + + // Check if we already posted this comment + const comments = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number + }); + + const botComment = comments.data.find(comment => + comment.user.type === 'Bot' && + comment.body.includes('organization account') + ); + + if (botComment) { + console.log('Comment about organization account already exists, skipping'); + return; + } + + // Sanitize username - GitHub usernames can only contain alphanumeric characters and hyphens + const username = pr.user.login.replace(/[^a-zA-Z0-9-]/g, ''); + + const commentBody = `Hi @${username}! 👋 + +⚠️ We noticed that this pull request comes from an organization account, +which will prevent our CI workflow from working correctly. + +GitHub does not allow the "Allow edits from maintainers" option for forks in organizations (see [discussion](https://github.com/orgs/community/discussions/5634)). +Our CI needs this permission to commit turtle files and clean up Excel files. + +**This PR cannot be merged as-is.** Please: +1. Fork voc4cat to your personal GitHub account +2. Create a feature branch with your changes +3. Submit a new PR from your personal fork +4. Close this PR + +Sorry for the inconvenience - this is a GitHub limitation, not our choice!`; + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body: commentBody + }); + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cfab8e92..fb285580 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,9 +8,12 @@ Thank you for your interest in contributing to the Voc4Cat vocabulary! This SKOS 2. **Edit** the Excel file to add/modify concepts 3. **Request a range of IDs** (for new concepts): [Create an issue](https://github.com/nfdi4cat/voc4cat/issues/new/choose) 4. **Submit** your Excel file in a pull request: + - Create a new branch for the changes in your fork and switch to it - Place file in `inbox-excel-vocabs/` folder - Keep the filename as `voc4cat.xlsx` - - Describe your changes in the PR description + - Create a PR and describe your changes in the PR description + +For more details, see [How to contribute?](https://nfdi4cat.github.io/voc4cat/docs_usage/how-to-contribute.html) ## Important Guidelines @@ -18,6 +21,8 @@ Thank you for your interest in contributing to the Voc4Cat vocabulary! This SKOS - **Break up large changes**: Split contributions of 50+ concepts into smaller chunks (~20 changes each) - **Use Excel workflow only**: Never edit Turtle (.ttl) files directly - **ID ranges required**: Request your ID range before adding new concepts +- **Use feature branches**: Create a new branch for your changes instead of committing to your fork's main branch +- **Classify concepts properly**: Ensure new concepts are linked to the hierarchy via broader concepts ## Documentation @@ -33,9 +38,15 @@ For detailed guidelines and step-by-step instructions, see: 1. CI/CD pipeline automatically processes your Excel file 2. Turtle files are generated and validated -3. Updated Excel file is created from the processed data -4. Reviewers will check your contribution -5. Upon approval, your changes are merged and published +3. Automated checks provide helpful feedback: + - Detects PRs from main branch (suggests using feature branches) + - Identifies organization account issues that will block CI + - GitHub Copilot may provide additional review guidance +4. Updated Excel file is created from the processed data +5. Reviewers will check your contribution +6. Upon approval, your changes are merged and published + +**Note**: Automated checks are informational and won't block your PR (except organization accounts due to GitHub limitations). ## Questions or Issues?