mirror of
https://github.com/avelino/awesome-go.git
synced 2026-04-11 02:11:43 +08:00
feat: add automated PR quality checks for CONTRIBUTING.md standards
- Add `.github/scripts/check-quality.js` to extract PR links and validate minimum standards: - Checks repo accessibility, go.mod, SemVer release, Go Report Card (A- or better), coverage, and pkg.go.dev. - Outputs markdown report and sets fail status for critical issues. - Add `.github/scripts/extract-pr-links.js` to extract and format PR body links for review. - Add `.github/workflows/pr-quality-check.yaml` to run quality checks on PRs, post results as comments, sync labels, and fail PR if critical checks fail. - Update `CONTRIBUTING.md` to clarify required PR body links and quality standards. - Update `.github/workflows/pull-request-first-comment.yaml` to support new automation. This improves PR review automation and enforces minimum quality standards for new submissions. Signed-off-by: Avelino <31996+avelino@users.noreply.github.com>
This commit is contained in:
parent
ffd7b28c08
commit
12dc8e9fde
214
.github/scripts/check-quality.js
vendored
Normal file
214
.github/scripts/check-quality.js
vendored
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
PR Quality Checks `CONTRIBUTING.md`
|
||||
- Extracts links from PR body (repo, pkg.go.dev, goreportcard, coverage)
|
||||
- Validates minimum standards from CONTRIBUTING.md (basic automated subset):
|
||||
* Repo accessible and not archived
|
||||
* Has go.mod and at least one SemVer release
|
||||
* Go Report Card reachable with acceptable grade (A- or better)
|
||||
* Coverage link reachable
|
||||
* pkg.go.dev page exists
|
||||
- Outputs a markdown report as `comment` and sets `fail=true` if critical checks fail
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const https = require('https');
|
||||
|
||||
const GITHUB_OUTPUT = process.env.GITHUB_OUTPUT;
|
||||
|
||||
function readEvent() {
|
||||
try {
|
||||
return JSON.parse(fs.readFileSync(process.env.GITHUB_EVENT_PATH, 'utf8'));
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
function capture(body, regex) {
|
||||
const m = body.match(regex);
|
||||
return m && m[1] ? m[1].trim() : '';
|
||||
}
|
||||
|
||||
function httpHeadOrGet(url) {
|
||||
return new Promise((resolve) => {
|
||||
const req = https.request(url, { method: 'HEAD' }, (res) => {
|
||||
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 400) {
|
||||
resolve({ ok: true, status: res.statusCode });
|
||||
} else if (res.statusCode && res.statusCode >= 400 && res.statusCode < 500) {
|
||||
resolve({ ok: false, status: res.statusCode });
|
||||
} else {
|
||||
// retry with GET on redirect or unsupported HEAD
|
||||
const req2 = https.request(url, { method: 'GET' }, (res2) => {
|
||||
resolve({ ok: (res2.statusCode || 500) < 400, status: res2.statusCode });
|
||||
});
|
||||
req2.on('error', () => resolve({ ok: false }));
|
||||
req2.end();
|
||||
return;
|
||||
}
|
||||
});
|
||||
req.on('error', () => resolve({ ok: false }));
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
function parseGithubRepo(repoUrl) {
|
||||
try {
|
||||
const u = new URL(repoUrl);
|
||||
if (u.hostname !== 'github.com') return null;
|
||||
const [, owner, repo] = u.pathname.split('/');
|
||||
if (!owner || !repo) return null;
|
||||
return { owner, repo };
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchJson(url, headers = {}) {
|
||||
return new Promise((resolve) => {
|
||||
https
|
||||
.get(url, { headers }, (res) => {
|
||||
let data = '';
|
||||
res.on('data', (c) => (data += c));
|
||||
res.on('end', () => {
|
||||
try {
|
||||
resolve(JSON.parse(data));
|
||||
} catch {
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
})
|
||||
.on('error', () => resolve(null));
|
||||
});
|
||||
}
|
||||
|
||||
async function checkGithubRepo(repoUrl) {
|
||||
const parsed = parseGithubRepo(repoUrl);
|
||||
if (!parsed) return { ok: false, reason: 'invalid repo url' };
|
||||
const { owner, repo } = parsed;
|
||||
const base = 'https://api.github.com';
|
||||
const headers = { 'User-Agent': 'awesome-go-quality-check' };
|
||||
const repoData = await fetchJson(`${base}/repos/${owner}/${repo}`, headers);
|
||||
if (!repoData) return { ok: false, reason: 'repo api not reachable' };
|
||||
if (repoData.archived) return { ok: false, reason: 'repo is archived' };
|
||||
const hasGoMod = await fetchJson(`${base}/repos/${owner}/${repo}/contents/go.mod`, headers);
|
||||
const releases = await fetchJson(`${base}/repos/${owner}/${repo}/releases`, headers);
|
||||
const hasRelease = Array.isArray(releases) && releases.some((r) => /^v\d+\.\d+\.\d+/.test(r.tag_name || ''));
|
||||
return {
|
||||
ok: Boolean(hasGoMod && hasGoMod.name === 'go.mod' && hasRelease),
|
||||
reason: !hasGoMod ? 'missing go.mod' : !hasRelease ? 'missing semver release' : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
async function checkGoReportCard(url) {
|
||||
// Accept A- or better
|
||||
const res = await httpHeadOrGet(url);
|
||||
if (!res.ok) return { ok: false, reason: 'unreachable' };
|
||||
// Fetch page to parse grade (best-effort)
|
||||
return new Promise((resolve) => {
|
||||
https
|
||||
.get(url, (res2) => {
|
||||
let html = '';
|
||||
res2.on('data', (c) => (html += c));
|
||||
res2.on('end', () => {
|
||||
const m = html.match(/Grade:\s*([A-F][+-]?)/i);
|
||||
if (!m) return resolve({ ok: true, grade: 'unknown' });
|
||||
const grade = m[1].toUpperCase();
|
||||
const pass = /^A[-+]?$/.test(grade);
|
||||
resolve({ ok: pass, grade });
|
||||
});
|
||||
})
|
||||
.on('error', () => resolve({ ok: false, reason: 'fetch error' }));
|
||||
});
|
||||
}
|
||||
|
||||
async function checkPkgGoDev(url) {
|
||||
const res = await httpHeadOrGet(url);
|
||||
return { ok: res.ok };
|
||||
}
|
||||
|
||||
async function checkCoverage(url) {
|
||||
const res = await httpHeadOrGet(url);
|
||||
return { ok: res.ok };
|
||||
}
|
||||
|
||||
function setOutput(name, value) {
|
||||
if (!GITHUB_OUTPUT) return;
|
||||
fs.appendFileSync(GITHUB_OUTPUT, `${name}<<EOF\n${value}\nEOF\n`);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const event = readEvent();
|
||||
const body = (event.pull_request && event.pull_request.body) || '';
|
||||
const repo = capture(body, /forge\s+link[^:]*:\s*(https?:\/\/(?:github\.com|gitlab\.com|bitbucket\.org)\/\S+)/i);
|
||||
const pkg = capture(body, /pkg\.go\.dev:\s*(https?:\/\/pkg\.go\.dev\/\S+)/i);
|
||||
const gorep = capture(body, /goreportcard\.com:\s*(https?:\/\/goreportcard\.com\/\S+)/i);
|
||||
const coverage = capture(body, /coverage[^:]*:\s*(https?:\/\/(?:coveralls\.io|codecov\.io)\/\S+)/i);
|
||||
|
||||
const results = [];
|
||||
let criticalFail = false;
|
||||
let repoOk = false, pkgOk = false, gorepOk = false; // track core checks
|
||||
|
||||
if (!repo) {
|
||||
results.push('- Repo link: missing');
|
||||
criticalFail = true;
|
||||
} else {
|
||||
const r = await checkGithubRepo(repo);
|
||||
if (!r.ok) { results.push(`- Repo: FAIL (${r.reason || 'unknown'})`); criticalFail = true; }
|
||||
else { results.push('- Repo: OK'); repoOk = true; }
|
||||
}
|
||||
|
||||
if (!pkg) {
|
||||
results.push('- pkg.go.dev: missing');
|
||||
criticalFail = true;
|
||||
} else {
|
||||
const r = await checkPkgGoDev(pkg);
|
||||
if (!r.ok) { results.push('- pkg.go.dev: FAIL (unreachable)'); criticalFail = true; }
|
||||
else { results.push('- pkg.go.dev: OK'); pkgOk = true; }
|
||||
}
|
||||
|
||||
if (!gorep) {
|
||||
results.push('- goreportcard: missing');
|
||||
criticalFail = true;
|
||||
} else {
|
||||
const r = await checkGoReportCard(gorep);
|
||||
if (!r.ok) { results.push(`- goreportcard: FAIL (${r.reason || r.grade || 'unreachable/low grade'})`); criticalFail = true; }
|
||||
else { results.push(`- goreportcard: OK${r.grade ? ` (grade ${r.grade})` : ''}`); gorepOk = true; }
|
||||
}
|
||||
|
||||
let coverageOk = false;
|
||||
if (!coverage) {
|
||||
results.push('- coverage: missing');
|
||||
} else {
|
||||
const r = await checkCoverage(coverage);
|
||||
if (!r.ok) { results.push('- coverage: FAIL (unreachable)'); }
|
||||
else { results.push('- coverage: OK'); coverageOk = true; }
|
||||
}
|
||||
|
||||
const header = 'Automated Quality Checks (from CONTRIBUTING minimum standards)';
|
||||
const note = 'These checks are a best-effort automation and do not replace human review.';
|
||||
const summary = results.join('\n');
|
||||
const comment = [header, '', summary, '', note].join('\n');
|
||||
|
||||
// Labels to reflect status
|
||||
const knownLabels = ['quality:ok', 'quality:fail', 'needs-info', 'needs-coverage'];
|
||||
const labels = [];
|
||||
const missingInfo = (!repo || !pkg || !gorep);
|
||||
if (missingInfo) labels.push('needs-info');
|
||||
if (!coverageOk) labels.push('needs-coverage');
|
||||
if (criticalFail) labels.push('quality:fail');
|
||||
if (!criticalFail && repoOk && pkgOk && gorepOk) labels.push('quality:ok');
|
||||
|
||||
setOutput('comment', comment);
|
||||
setOutput('fail', criticalFail ? 'true' : 'false');
|
||||
setOutput('labels', JSON.stringify(labels));
|
||||
}
|
||||
|
||||
main().catch((e) => {
|
||||
const msg = `Quality checks failed to run: ${e?.message || e}`;
|
||||
if (GITHUB_OUTPUT) {
|
||||
fs.appendFileSync(GITHUB_OUTPUT, `comment<<EOF\n${msg}\nEOF\n`);
|
||||
fs.appendFileSync(GITHUB_OUTPUT, `fail<<EOF\ntrue\nEOF\n`);
|
||||
}
|
||||
process.exitCode = 0; // Do not crash the job here; let the fail step handle it
|
||||
});
|
||||
|
||||
|
||||
69
.github/scripts/extract-pr-links.js
vendored
Normal file
69
.github/scripts/extract-pr-links.js
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
Extract PR links from the pull request body and expose a single step output `body`.
|
||||
This script reads the GitHub event payload from GITHUB_EVENT_PATH, parses the PR body,
|
||||
captures the four URLs (repo, pkg.go.dev, goreportcard.com, coverage service),
|
||||
and writes a formatted comment to GITHUB_OUTPUT as `body=<comment>`.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
function readEventPayload() {
|
||||
const eventPath = process.env.GITHUB_EVENT_PATH;
|
||||
if (!eventPath || !fs.existsSync(eventPath)) {
|
||||
return {};
|
||||
}
|
||||
const content = fs.readFileSync(eventPath, 'utf8');
|
||||
try {
|
||||
return JSON.parse(content);
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
function capture(body, regex) {
|
||||
const match = body.match(regex);
|
||||
return match && match[1] ? match[1] : '';
|
||||
}
|
||||
|
||||
function buildComment({ repo, pkg, gorep, coverage }) {
|
||||
const repoOut = repo || 'not provided';
|
||||
const pkgOut = pkg || 'not provided';
|
||||
const gorepOut = gorep || 'not provided';
|
||||
const coverageOut = coverage || 'not provided';
|
||||
|
||||
return [
|
||||
'Thank you for contributing to [awesome-go](https://awesome-go.com/). We will review your contribution as soon as possible.',
|
||||
'',
|
||||
'Make sure you add the links in the body of the pull request that are requested in the [contribution guide](https://github.com/avelino/awesome-go/blob/main/CONTRIBUTING.md):',
|
||||
`- repo link: @${repoOut}`,
|
||||
`- pkg.go.dev: @${pkgOut}`,
|
||||
`- goreportcard.com: @${gorepOut}`,
|
||||
`- coverage: @${coverageOut}`,
|
||||
'',
|
||||
'> Your project is under review. It may take a few days to be approved.'
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
function main() {
|
||||
const event = readEventPayload();
|
||||
const prBody = (event.pull_request && event.pull_request.body) || '';
|
||||
|
||||
const repo = capture(prBody, /forge\s+link[^:]*:\s*(https?:\/\/(?:github\.com|gitlab\.com|bitbucket\.org)\/\S+)/i);
|
||||
const pkg = capture(prBody, /pkg\.go\.dev:\s*(https?:\/\/pkg\.go\.dev\/\S+)/i);
|
||||
const gorep = capture(prBody, /goreportcard\.com:\s*(https?:\/\/goreportcard\.com\/\S+)/i);
|
||||
const coverage = capture(prBody, /coverage[^:]*:\s*(https?:\/\/(?:coveralls\.io|codecov\.io)\/\S+)/i);
|
||||
|
||||
const comment = buildComment({ repo, pkg, gorep, coverage });
|
||||
|
||||
const outPath = process.env.GITHUB_OUTPUT;
|
||||
if (!outPath) {
|
||||
console.log(comment);
|
||||
return;
|
||||
}
|
||||
// Write to GITHUB_OUTPUT
|
||||
fs.appendFileSync(outPath, `body<<EOF\n${comment}\nEOF\n`);
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
|
||||
43
.github/workflows/pr-quality-check.yaml
vendored
Normal file
43
.github/workflows/pr-quality-check.yaml
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
name: PR Quality Checks
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, edited, synchronize, reopened]
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
quality:
|
||||
runs-on: ubuntu-latest
|
||||
environment: action
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
- name: Run quality checks
|
||||
id: check
|
||||
continue-on-error: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: node .github/scripts/check-quality.js
|
||||
- name: Post quality report comment
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: ${{ steps.check.outputs.comment }}
|
||||
- name: Sync labels
|
||||
uses: actions-ecosystem/action-add-labels@v1
|
||||
if: ${{ steps.check.outputs.labels != '' }}
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
labels: ${{ join(fromJson(steps.check.outputs.labels), '\n') }}
|
||||
- name: Fail if critical checks failed
|
||||
if: ${{ steps.check.outputs.fail == 'true' }}
|
||||
run: |
|
||||
echo "Critical quality checks failed."
|
||||
exit 1
|
||||
@ -14,18 +14,17 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
- name: extract links from PR body
|
||||
id: extract
|
||||
run: node .github/scripts/extract-pr-links.js
|
||||
- name: first comment
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
Thank you for contributing to [awesome-go](https://awesome-go.com/). We will review your contribution as soon as possible.
|
||||
|
||||
Make sure you add the links in the body of the pull request that are requested in the [contribution guide](https://github.com/avelino/awesome-go/blob/main/CONTRIBUTING.md):
|
||||
- repo link
|
||||
- pkg.go.dev
|
||||
- goreportcard.com
|
||||
- coverage
|
||||
|
||||
> Your project is under review. It may take a few days to be approved.
|
||||
body: ${{ steps.extract.outputs.body }}
|
||||
|
||||
126
CONTRIBUTING.md
126
CONTRIBUTING.md
@ -1,25 +1,55 @@
|
||||
This resource was made by the Go community and wouldn't be possible without you!
|
||||
This resource was made by the Go community and wouldn't be possible without you!
|
||||
We appreciate and recognize [all contributors](https://github.com/avelino/awesome-go/graphs/contributors).
|
||||
|
||||
|
||||
# Contribution Guidelines
|
||||
|
||||
> Please be aware that we want to accept your contribution, but we have **some rules to keep the minimum quality** of the packages listed here. All reviews are **not personal feedback**, even if you are a _developer reviewing your contribution_. **Sorry, if we can't meet your expectations; we do our best**.
|
||||
|
||||
- **To add, remove, or change things on the list:** Submit a pull request
|
||||
|
||||
To set this list apart from and complement the excellent [Go wiki Projects page](https://golang.org/wiki/Projects),
|
||||
## Table of Contents
|
||||
|
||||
- [Quick checklist](#quick-checklist)
|
||||
- [Quality standards](#quality-standards)
|
||||
- [Preparing for review](#preparing-for-review)
|
||||
- [Local validations (optional)](#local-validations-optional)
|
||||
- [How to add an item to the list](#how-to-add-an-item-to-the-list)
|
||||
- [Examples of good and bad entries](#examples-of-good-and-bad-entries)
|
||||
- [PR body example](#pr-body-example)
|
||||
- [Congrats, your project got accepted - what now?](#congrats-your-project-got-accepted---what-now)
|
||||
- [Maintenance expectations for projects listed here](#maintenance-expectations-for-projects-listed-here)
|
||||
- [How to remove an item from the list](#how-to-remove-an-item-from-the-list)
|
||||
- [Maintainers](#maintainers)
|
||||
- [Reporting issues](#reporting-issues)
|
||||
- [How decisions are made](#how-decisions-are-made)
|
||||
- [How to become a contributor?](#how-to-become-a-contributor)
|
||||
- [How to become an ~~"official maintainer"~~?](#how-to-become-an-official-maintainer)
|
||||
|
||||
## Quick checklist
|
||||
|
||||
Before opening a pull request, please ensure the following:
|
||||
|
||||
- One PR adds, removes, or changes only one item.
|
||||
- The item is in the correct category and in alphabetical order.
|
||||
- The link text is the exact project/package name.
|
||||
- The description is concise, non-promotional, and ends with a period.
|
||||
- The repository has: at least 5 months of history, an open source license, a `go.mod`, and at least one SemVer release (vX.Y.Z).
|
||||
- Documentation in English: README and pkg.go.dev doc comments for public APIs.
|
||||
- Tests meet the coverage guideline (≥80% for non-data packages, ≥90% for data packages) when applicable.
|
||||
- Include links in the PR body to pkg.go.dev, Go Report Card, and a coverage report.
|
||||
- For ongoing development: issues and PRs are responded to within ~2 weeks; or, if the project is mature/stable, there are no bug reports older than 6 months.
|
||||
|
||||
To set this list apart from and complement the excellent [Go wiki Projects page](https://go.dev/wiki/Projects),
|
||||
and other lists, awesome-go is a specially curated list of high-quality, actively maintained Go packages and resources.
|
||||
|
||||
Please contribute links to packages/projects you have used or are familiar with. This will help ensure high-quality entries.
|
||||
|
||||
> the maintainers do not work full-time on the project, meaning that we do not have a set periodicity for reviewing contributions - rest assured that we will do our best to review and eventually accept contributions
|
||||
|
||||
|
||||
## Quality standards
|
||||
|
||||
To be on the list, project repositories should adhere to the following quality standards.
|
||||
(https://goreportcard.com/report/github.com/ **github_user** / **github_repo**):
|
||||
To be on the list, project repositories should adhere to the following quality standards.
|
||||
(<https://goreportcard.com/report/github.com/> **github_user** / **github_repo**):
|
||||
|
||||
- have at least 5 months of history since the first commit.
|
||||
- have an **open source license**, [see list of allowed licenses](https://opensource.org/licenses/alphabetical);
|
||||
@ -35,7 +65,6 @@ To be on the list, project repositories should adhere to the following quality s
|
||||
|
||||
Categories must have at least 3 items.
|
||||
|
||||
|
||||
## Preparing for review
|
||||
|
||||
Projects listed must have the following in their documentation. When submitting, you will be asked
|
||||
@ -46,10 +75,30 @@ to provide them.
|
||||
- A link to a code coverage report
|
||||
|
||||
One way to accomplish the above is to add badges to your project's README file.
|
||||
- Use https://pkg.go.dev/badge/ to create the pkg.go.dev link.
|
||||
- Go to https://goreportcard.com/ to generate a Go Report Card report, then click on the report badge in the upper-right corner to see details on how to add the badge to your README.
|
||||
|
||||
- Use <https://pkg.go.dev/badge/> to create the pkg.go.dev link.
|
||||
- Go to <https://goreportcard.com/> to generate a Go Report Card report, then click on the report badge in the upper-right corner to see details on how to add the badge to your README.
|
||||
- Codecov, coveralls, and gocover all offer ways to create badges for code coverage reports. Another option is to generate a badge as part of a continuous integration process. See [Code Coverage](COVERAGE.md) for an example.
|
||||
|
||||
## Local validations (optional)
|
||||
|
||||
While automated checks run on pull requests, doing a quick local validation helps speed up reviews:
|
||||
|
||||
- Repository readiness
|
||||
- Ensure `go.mod` exists and there is at least one SemVer release (e.g., `v1.2.3`).
|
||||
- Confirm the project has an open source license.
|
||||
- Documentation readiness
|
||||
- README is in English and explains what the project does and how to use it.
|
||||
- Public APIs have doc comments and the pkg.go.dev page loads.
|
||||
- Quality reports
|
||||
- Go Report Card is reachable with grade A- or better.
|
||||
- Coverage link (Codecov, Coveralls, etc.) is reachable.
|
||||
- Local coverage sanity check (optional):
|
||||
- `go test ./... -coverprofile=coverage.out`
|
||||
- `go tool cover -func=coverage.out` (check percentage)
|
||||
- List formatting
|
||||
- Correct category and alphabetical order.
|
||||
- Link text equals the project name; description ends with a period and is non-promotional.
|
||||
|
||||
## How to add an item to the list
|
||||
|
||||
@ -67,31 +116,63 @@ that the resulting list has at least 3 projects in every category, and that the
|
||||
|
||||
Fill out the template in your PR with the links asked for. If you accidentally remove the PR template from the submission, you can find it [here](https://github.com/avelino/awesome-go/blob/main/.github/PULL_REQUEST_TEMPLATE.md).
|
||||
|
||||
### Examples of good and bad entries
|
||||
|
||||
Good:
|
||||
|
||||
```md
|
||||
- [project-name](https://github.com/org/project) - Short, clear description.
|
||||
```
|
||||
|
||||
Bad (not alphabetical):
|
||||
|
||||
```md
|
||||
- [zeta](https://github.com/org/zeta) - ...
|
||||
- [alpha](https://github.com/org/alpha) - ...
|
||||
```
|
||||
|
||||
Bad (promotional, missing period, or mismatched link text):
|
||||
|
||||
```md
|
||||
- [Awesome Best Project Ever!!!](https://github.com/org/project) - The ultimate, world-class solution
|
||||
```
|
||||
|
||||
### PR body example
|
||||
|
||||
Provide these links in the PR body to speed up review:
|
||||
|
||||
```md
|
||||
Forge link: https://github.com/org/project
|
||||
pkg.go.dev: https://pkg.go.dev/github.com/org/project
|
||||
goreportcard.com: https://goreportcard.com/report/github.com/org/project
|
||||
Coverage: https://app.codecov.io/gh/org/project
|
||||
```
|
||||
|
||||
## Congrats, your project got accepted - what now?
|
||||
You are an outstanding project now! Feel encouraged to tell others about it by adding one of these badges:
|
||||
[](https://github.com/avelino/awesome-go)
|
||||
|
||||
You are an outstanding project now! Feel encouraged to tell others about it by adding one of these badges:
|
||||
[](https://github.com/avelino/awesome-go)
|
||||
[](https://github.com/avelino/awesome-go)
|
||||
|
||||
```md
|
||||
[](https://github.com/avelino/awesome-go)
|
||||
[](https://github.com/avelino/awesome-go)
|
||||
[](https://github.com/avelino/awesome-go)
|
||||
```
|
||||
|
||||
|
||||
## Maintenance expectations for projects listed here
|
||||
|
||||
To prevent removal from awesome-go, your project must maintain the following quality standards.
|
||||
|
||||
- Development should be ongoing and maintain code quality. Official releases should be at least once a year if the project is ongoing.
|
||||
- Or, if development has halted because the project is mature and stable, that can be demonstrated by having no bug reports in the Issues list that are older than 6 months.
|
||||
- All links to quality reports should be to the most recent official release or current ongoing development.
|
||||
|
||||
Highly recommended but not required:
|
||||
|
||||
- A continuous integration process to be part of the ongoing development process
|
||||
- That the project uses a pull-request process, and the owners do not commit directly to the repository
|
||||
- That the pull-request process requires the continuous-integration tests to pass before a pull request can be merged
|
||||
|
||||
|
||||
## How to remove an item from the list
|
||||
|
||||
- Open a pull request that deletes the line of the project in question.
|
||||
@ -107,16 +188,15 @@ If the project is hosted on GitHub, include a link to the project's submitter an
|
||||
that they will be notified of the desire to remove the project and have an opportunity to respond.
|
||||
The link should be of the form @githubID.
|
||||
|
||||
If the project is not hosted on GitHub, open an issue at the project in question's repository linking to the PR
|
||||
If the project is not hosted on GitHub, open an issue at the project in question's repository linking to the PR
|
||||
and stating the following:
|
||||
|
||||
>This project is currently listed at awesome-go at https://github.com/avelino/awesome-go.
|
||||
>This project is currently listed at awesome-go at <https://github.com/avelino/awesome-go>.
|
||||
However, it appears that the project is not maintaining the quality standards required to continue to be listed at the awesome-go project.
|
||||
This project is scheduled to be removed within 2 weeks of this posting. To continue to be listed at awesome-go, please respond at:
|
||||
-- link to above PR --
|
||||
|
||||
Then, comment on your PR at awesome-go with a link to the removal issue at the project.
|
||||
|
||||
Then, comment on your PR at awesome-go with a link to the removal issue at the project.
|
||||
|
||||
## Maintainers
|
||||
|
||||
@ -126,7 +206,6 @@ The maintainers will review your PR and notify you and tag it in case any
|
||||
information is still missing. They will wait 15 days for your interaction, after
|
||||
that the PR will be closed.
|
||||
|
||||
|
||||
## Reporting issues
|
||||
|
||||
Please open an issue if you would like to discuss anything that could be improved or have suggestions for making the list a more valuable resource. We realize sometimes packages fall into abandonment or have breaking builds for extended periods of time, so if you see that, feel free to change its listing, or please let us know. We also realize that sometimes projects are just going through transitions or are more experimental in nature. These can still be cool, but we can indicate them as transitory or experimental.
|
||||
@ -135,12 +214,10 @@ Removal changes will not be applied until they have been pending for a minimum o
|
||||
|
||||
Thanks, everyone!
|
||||
|
||||
|
||||
## How decisions are made
|
||||
|
||||
The official group of maintainers has the final decision on what PRs are accepted. Discussions are made openly in issues. Decisions are made by consensus.
|
||||
|
||||
|
||||
## How to become a contributor?
|
||||
|
||||
awesome-go is an open source project (created and maintained by the community), we are always open to new people to help us review the contributions (pull requests), **you don't need permission** or _name on the maintainers list_ to review a contribution and mark it as **LGTM**.
|
||||
@ -151,15 +228,14 @@ Now that you've read it, let's go!
|
||||
|
||||
Go into the pull requests (PR) and look at the following aspects:
|
||||
|
||||
* **shared links in the body of the PR:** they need to be valid and follow the quality specified above
|
||||
* **check that the link added to `README.md`** is the same as the link to the repository mentioned in the body of the PR.
|
||||
* **is it in the correct category?**
|
||||
- **shared links in the body of the PR:** they need to be valid and follow the quality specified above
|
||||
- **check that the link added to `README.md`** is the same as the link to the repository mentioned in the body of the PR.
|
||||
- **is it in the correct category?**
|
||||
|
||||
If everything is OK, mark the PR as approved, [read this documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/reviewing-proposed-changes-in-a-pull-request#starting-a-review) on how to do it.
|
||||
|
||||
**Welcome to awesome-go!**
|
||||
|
||||
|
||||
## How to become an ~~"official maintainer"~~?
|
||||
|
||||
We don't give this name to people who are allowed to accept the PR.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user