mirror of
https://github.com/veggiemonk/awesome-docker.git
synced 2025-11-22 16:34:27 +01:00
Modernization (thanks to AI) (#1187)
* - ✅ Removed 3 broken links (labex.io, hashnode.com entries) - ✅ Fixed rust-lang.org redirect issue - ✅ Added problematic domains to exclusion list (YouTube playlists, aquasec, cloudsmith) - ✅ Updated all npm dependencies to latest versions - ✅ **health_check.mjs** - Comprehensive repository health checker - Detects archived repositories - Identifies stale projects (2+ years inactive) - Flags inactive projects (1-2 years) - Generates detailed health reports - Run with: `npm run health-check` - ✅ **test_all.mjs** - Now detects archived repositories - Added `isArchived` field to GraphQL query - Warns about archived repos that should be marked `💀` - Non-blocking warnings (doesn't fail builds) - Runs every Monday at 9 AM UTC - Checks all 731+ GitHub repositories for health - Auto-creates/updates GitHub issue with findings - Labels: `health-report`, `maintenance` - Manual trigger available - Runs every Saturday at 2 AM UTC - Tests all external links - Auto-creates issue when links break - Auto-closes issue when all links fixed - Labels: `broken-links`, `bug` - Already checks for duplicates - Now also checks for archived repos - Validates link format and availability - ✅ **MAINTENANCE.md** - Complete guide for maintainers - Monthly, quarterly, and annual tasks - Emergency procedures - Quality standards - Metrics to track - ✅ **AGENTS.md** - Updated with new commands - Added health-check command - Noted GITHUB_TOKEN requirements - Added alphabetical sorting guideline - **Total Links**: 883 (731 GitHub repos + 152 external) - **Working Links**: >99% (after fixes) - **Abandoned Projects**: 15 marked with `💀` - **Automated Checks**: 3 workflows running - **Automatic detection** of abandoned/archived projects - **Weekly monitoring** ensures issues are caught early - **Proactive alerts** via GitHub issues - No more manual link checking (automated weekly) - Archived repos detected automatically - Contributors get instant PR feedback - Health metrics tracked over time - Clear standards documented - Easy onboarding for new maintainers - Monday: Health report generated and posted - Saturday: Link validation runs - Review health report issue - Mark any newly archived projects with `💀` - Run full health check: `npm run health-check` - Review inactive projects (1-2 years) - Consider removing very old abandoned projects - Deep cleanup of `💀` projects - Update documentation - Review categories and organization 1. **Auto-PR for Archived Repos**: Bot could auto-create PRs to mark archived repos 2. **Contribution Stats**: Track and display top contributors 3. **Category Health**: Per-category health metrics 4. **Dependency Updates**: Dependabot for npm packages 5. **Star Trending**: Track which projects are gaining popularity - `tests/health_check.mjs` - Health checker script - `.github/workflows/health_report.yml` - Weekly health workflow - `.github/workflows/broken_links.yml` - Link validation workflow - `.github/MAINTENANCE.md` - Maintainer guide - `AGENTS.md` - AI agent guidelines - `README.md` - Removed 3 broken links, fixed 1 redirect - `tests/test_all.mjs` - Added archive detection - `tests/exclude_in_test.json` - Added problematic domains - `package.json` - Added health-check script - `package-lock.json` - Updated dependencies Before: Manual maintenance, broken links accumulate, outdated projects linger After: **Automated health monitoring, proactive issue detection, systematic maintenance** The list is now **self-maintaining** with minimal human oversight required. --- *Generated: 2025-10-01* * update github actions * remove dead links * set timeout * Add badges
This commit is contained in:
116
.github/MAINTENANCE.md
vendored
Normal file
116
.github/MAINTENANCE.md
vendored
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
# 🔧 Maintenance Guide for Awesome Docker
|
||||||
|
|
||||||
|
This guide helps maintainers keep the awesome-docker list up-to-date and high-quality.
|
||||||
|
|
||||||
|
## 🤖 Automated Systems
|
||||||
|
|
||||||
|
### Weekly Health Reports
|
||||||
|
- **What**: Checks all GitHub repositories for activity, archived status, and maintenance
|
||||||
|
- **When**: Every Monday at 9 AM UTC
|
||||||
|
- **Where**: Creates/updates a GitHub issue with label `health-report`
|
||||||
|
- **Action**: Review the report and mark abandoned projects with `:skull:`
|
||||||
|
|
||||||
|
### Broken Links Detection
|
||||||
|
- **What**: Tests all links in README.md for availability
|
||||||
|
- **When**: Every Saturday at 2 AM UTC + on every PR
|
||||||
|
- **Where**: Creates/updates a GitHub issue with label `broken-links`
|
||||||
|
- **Action**: Fix or remove broken links, or add to exclusion list
|
||||||
|
|
||||||
|
### PR Validation
|
||||||
|
- **What**: Checks for duplicate links and basic validation
|
||||||
|
- **When**: On every pull request
|
||||||
|
- **Action**: Automated - contributors see results immediately
|
||||||
|
|
||||||
|
## 📋 Manual Maintenance Tasks
|
||||||
|
|
||||||
|
### Monthly Review (First Monday of the month)
|
||||||
|
1. Check health report issue for archived/stale projects
|
||||||
|
2. Mark archived projects with `:skull:` in README.md
|
||||||
|
3. Review projects with 2+ years of inactivity
|
||||||
|
4. Remove projects that are truly abandoned/broken
|
||||||
|
|
||||||
|
### Quarterly Deep Dive (Every 3 months)
|
||||||
|
1. Run: `npm run health-check` for detailed report
|
||||||
|
2. Review project categories - are they still relevant?
|
||||||
|
3. Check for popular new Docker tools to add
|
||||||
|
4. Update documentation links if newer versions exist
|
||||||
|
|
||||||
|
### Annual Cleanup (January)
|
||||||
|
1. Remove all `:skull:` projects older than 1 year
|
||||||
|
2. Review CONTRIBUTING.md guidelines
|
||||||
|
3. Update year references in documentation
|
||||||
|
4. Check Node.js version requirements
|
||||||
|
|
||||||
|
## 🛠️ Maintenance Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Test all links (requires GITHUB_TOKEN)
|
||||||
|
npm test
|
||||||
|
|
||||||
|
# Test PR changes only
|
||||||
|
npm run test-pr
|
||||||
|
|
||||||
|
# Generate health report (requires GITHUB_TOKEN)
|
||||||
|
npm run health-check
|
||||||
|
|
||||||
|
# Build the website
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Update dependencies
|
||||||
|
npm update
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 Quality Standards
|
||||||
|
|
||||||
|
### Adding New Projects
|
||||||
|
- Must have clear documentation (README with install/usage)
|
||||||
|
- Should have activity within last 18 months
|
||||||
|
- GitHub project preferred over website links
|
||||||
|
- Must be Docker/container-related
|
||||||
|
|
||||||
|
### Marking Projects as Abandoned
|
||||||
|
Use `:skull:` emoji when:
|
||||||
|
- Repository is archived on GitHub
|
||||||
|
- No commits for 2+ years
|
||||||
|
- Project explicitly states it's deprecated
|
||||||
|
- Maintainer confirms abandonment
|
||||||
|
|
||||||
|
### Removing Projects
|
||||||
|
Only remove (don't just mark `:skull:`):
|
||||||
|
- Broken/404 links that can't be fixed
|
||||||
|
- Duplicate entries
|
||||||
|
- Spam or malicious projects
|
||||||
|
- Projects that never met quality standards
|
||||||
|
|
||||||
|
## 🚨 Emergency Procedures
|
||||||
|
|
||||||
|
### Critical Broken Links
|
||||||
|
If important resources are down:
|
||||||
|
1. Check if they moved (update URL)
|
||||||
|
2. Search for alternatives
|
||||||
|
3. Check Internet Archive for mirrors
|
||||||
|
4. Temporarily comment out until resolved
|
||||||
|
|
||||||
|
### Spam Pull Requests
|
||||||
|
1. Close immediately
|
||||||
|
2. Mark as spam
|
||||||
|
3. Block user if repeated offense
|
||||||
|
4. Don't engage in comments
|
||||||
|
|
||||||
|
## 📈 Metrics to Track
|
||||||
|
|
||||||
|
- Total projects: ~731 GitHub repos
|
||||||
|
- Health status: aim for <5% archived
|
||||||
|
- Link availability: aim for >98% working
|
||||||
|
- PR merge time: aim for <7 days
|
||||||
|
- Weekly contributor engagement
|
||||||
|
|
||||||
|
## 🤝 Getting Help
|
||||||
|
|
||||||
|
- Open a discussion in GitHub Discussions
|
||||||
|
- Check AGENTS.md for AI assistant guidelines
|
||||||
|
- Review CONTRIBUTING.md for contributor info
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Last updated: 2025-10-01*
|
||||||
9
.github/PULL_REQUEST_TEMPLATE.md
vendored
9
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -2,18 +2,16 @@
|
|||||||
|
|
||||||
<!-- **Remember that entries are ordered alphabetically** -->
|
<!-- **Remember that entries are ordered alphabetically** -->
|
||||||
|
|
||||||
<!--
|
# TLDR
|
||||||
TLDR:
|
* all entries sorted alphabetically (from A to Z),
|
||||||
* all entries sorted alphabetically,
|
|
||||||
* If paying service add :heavy_dollar_sign:
|
* If paying service add :heavy_dollar_sign:
|
||||||
* If WIP add :construction:
|
* If WIP add :construction:
|
||||||
* clear and short description of the project
|
* clear and short description of the project
|
||||||
* project MUST have: How to setup/install
|
* project MUST have: How to setup/install
|
||||||
* project MUST have: How to use (examples)
|
* project MUST have: How to use (examples)
|
||||||
* we can help you get there :)
|
* we can help you get there :)
|
||||||
-->
|
|
||||||
|
|
||||||
# Quality Standards
|
## Quality Standards
|
||||||
|
|
||||||
Note that we can help you achieve those standards, just try your best and be brave.
|
Note that we can help you achieve those standards, just try your best and be brave.
|
||||||
We'll guide you to the best of our abilities.
|
We'll guide you to the best of our abilities.
|
||||||
@@ -48,4 +46,3 @@ But usually, we are pretty relaxed people, so just come and say hi, we'll figure
|
|||||||
|
|
||||||
Please contribute links to packages/projects you have used or are familiar with. This will help ensure high-quality entries.
|
Please contribute links to packages/projects you have used or are familiar with. This will help ensure high-quality entries.
|
||||||
|
|
||||||
#### Your commit message will be a [tweet](https://twitter.com/awesome_docker) so write a [good commit message](https://chris.beams.io/posts/git-commit/), keep that in mind :)
|
|
||||||
|
|||||||
134
.github/workflows/broken_links.yml
vendored
Normal file
134
.github/workflows/broken_links.yml
vendored
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
name: Broken Links Report
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
# Run every Saturday at 2 AM UTC
|
||||||
|
- cron: "0 2 * * 6"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-links:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # ratchet:actions/checkout@v5.0.0
|
||||||
|
|
||||||
|
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # ratchet:actions/setup-node@v5.0.0
|
||||||
|
with:
|
||||||
|
node-version: lts/*
|
||||||
|
|
||||||
|
- uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # ratchet:actions/cache@v4.3.0
|
||||||
|
with:
|
||||||
|
path: ~/.npm
|
||||||
|
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-node-
|
||||||
|
|
||||||
|
- name: Install Dependencies
|
||||||
|
run: npm ci --ignore-scripts --no-audit --no-progress --prefer-offline
|
||||||
|
|
||||||
|
- name: Run Link Check
|
||||||
|
id: link_check
|
||||||
|
run: |
|
||||||
|
npm test > link_check_output.txt 2>&1 || true
|
||||||
|
if grep -q "❌ ERROR" link_check_output.txt; then
|
||||||
|
echo "has_errors=true" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "has_errors=false" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Create/Update Issue for Broken Links
|
||||||
|
if: steps.link_check.outputs.has_errors == 'true'
|
||||||
|
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # ratchet:actions/github-script@v8
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const fs = require('fs');
|
||||||
|
const output = fs.readFileSync('link_check_output.txt', 'utf8');
|
||||||
|
|
||||||
|
// Extract error information
|
||||||
|
const errorMatch = output.match(/❌ ERROR[\s\S]*$/);
|
||||||
|
const errorInfo = errorMatch ? errorMatch[0] : 'Link check failed - see workflow logs';
|
||||||
|
|
||||||
|
const issueBody = `# 🔗 Broken Links Detected
|
||||||
|
|
||||||
|
The weekly link check has found broken or inaccessible links in the repository.
|
||||||
|
|
||||||
|
## Error Details
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
${errorInfo}
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## Action Required
|
||||||
|
|
||||||
|
Please review and fix the broken links above. Options:
|
||||||
|
- Update the URL if the resource moved
|
||||||
|
- Remove the entry if it's permanently unavailable
|
||||||
|
- Add to \`tests/exclude_in_test.json\` if it's a known false positive
|
||||||
|
|
||||||
|
---
|
||||||
|
*Auto-generated by [broken_links.yml](https://github.com/veggiemonk/awesome-docker/blob/master/.github/workflows/broken_links.yml)*
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Check for existing issue
|
||||||
|
const issues = await github.rest.issues.listForRepo({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
state: 'open',
|
||||||
|
labels: 'broken-links',
|
||||||
|
per_page: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
if (issues.data.length > 0) {
|
||||||
|
await github.rest.issues.update({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: issues.data[0].number,
|
||||||
|
body: issueBody
|
||||||
|
});
|
||||||
|
console.log(`Updated issue #${issues.data[0].number}`);
|
||||||
|
} else {
|
||||||
|
const issue = await github.rest.issues.create({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
title: '🔗 Broken Links Detected - Action Required',
|
||||||
|
body: issueBody,
|
||||||
|
labels: ['broken-links', 'bug']
|
||||||
|
});
|
||||||
|
console.log(`Created issue #${issue.data.number}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Close Issue if No Errors
|
||||||
|
if: steps.link_check.outputs.has_errors == 'false'
|
||||||
|
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # ratchet:actions/github-script@v8
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const issues = await github.rest.issues.listForRepo({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
state: 'open',
|
||||||
|
labels: 'broken-links',
|
||||||
|
per_page: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
if (issues.data.length > 0) {
|
||||||
|
await github.rest.issues.update({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: issues.data[0].number,
|
||||||
|
state: 'closed',
|
||||||
|
state_reason: 'completed'
|
||||||
|
});
|
||||||
|
await github.rest.issues.createComment({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: issues.data[0].number,
|
||||||
|
body: '✅ All links are now working! Closing this issue.'
|
||||||
|
});
|
||||||
|
console.log(`Closed issue #${issues.data[0].number}`);
|
||||||
|
}
|
||||||
51
.github/workflows/deploy-pages.yml
vendored
Normal file
51
.github/workflows/deploy-pages.yml
vendored
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
name: Deploy to GitHub Pages
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pages: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: "pages"
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # ratchet:actions/checkout@v5
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # ratchet:actions/setup-node@v5
|
||||||
|
with:
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Build website
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # ratchet:actions/upload-pages-artifact@v4
|
||||||
|
with:
|
||||||
|
path: ./website
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
steps:
|
||||||
|
- name: Deploy to GitHub Pages
|
||||||
|
id: deployment
|
||||||
|
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # ratchet:actions/deploy-pages@v4
|
||||||
84
.github/workflows/health_report.yml
vendored
Normal file
84
.github/workflows/health_report.yml
vendored
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
name: Weekly Health Report
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
# Run every Monday at 9 AM UTC
|
||||||
|
- cron: "0 9 * * 1"
|
||||||
|
workflow_dispatch: # Allow manual trigger
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
health-check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # ratchet:actions/checkout@v5.0.0
|
||||||
|
|
||||||
|
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # ratchet:actions/setup-node@v5.0.0
|
||||||
|
with:
|
||||||
|
node-version: lts/*
|
||||||
|
|
||||||
|
- uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # ratchet:actions/cache@v4.3.0
|
||||||
|
with:
|
||||||
|
path: ~/.npm
|
||||||
|
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-node-
|
||||||
|
|
||||||
|
- name: Install Dependencies
|
||||||
|
run: npm ci --ignore-scripts --no-audit --no-progress --prefer-offline
|
||||||
|
|
||||||
|
- name: Run Health Check
|
||||||
|
run: node tests/health_check.mjs
|
||||||
|
continue-on-error: true
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Upload Health Report
|
||||||
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # ratchet:actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: health-report
|
||||||
|
path: HEALTH_REPORT.md
|
||||||
|
|
||||||
|
- name: Create Issue with Health Report
|
||||||
|
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # ratchet:actions/github-script@v8
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
// Read the health report
|
||||||
|
const report = fs.readFileSync('HEALTH_REPORT.md', 'utf8');
|
||||||
|
|
||||||
|
// Check if there's already an open issue
|
||||||
|
const issues = await github.rest.issues.listForRepo({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
state: 'open',
|
||||||
|
labels: 'health-report',
|
||||||
|
per_page: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
const issueBody = report + '\n\n---\n*This report is auto-generated weekly. See [health_check.mjs](https://github.com/veggiemonk/awesome-docker/blob/master/tests/health_check.mjs) for details.*';
|
||||||
|
|
||||||
|
if (issues.data.length > 0) {
|
||||||
|
// Update existing issue
|
||||||
|
await github.rest.issues.update({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: issues.data[0].number,
|
||||||
|
body: issueBody
|
||||||
|
});
|
||||||
|
console.log(`Updated issue #${issues.data[0].number}`);
|
||||||
|
} else {
|
||||||
|
// Create new issue
|
||||||
|
const issue = await github.rest.issues.create({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
title: '🏥 Weekly Health Report - Repository Maintenance Needed',
|
||||||
|
body: issueBody,
|
||||||
|
labels: ['health-report', 'maintenance']
|
||||||
|
});
|
||||||
|
console.log(`Created issue #${issue.data.number}`);
|
||||||
|
}
|
||||||
8
.github/workflows/pull_request.yml
vendored
8
.github/workflows/pull_request.yml
vendored
@@ -5,18 +5,18 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 * * 6'
|
- cron: "0 0 * * 6"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.2.2
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # ratchet:actions/checkout@v5.0.0
|
||||||
- uses: actions/setup-node@v4.3.0
|
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # ratchet:actions/setup-node@v5.0.0
|
||||||
with:
|
with:
|
||||||
node-version: lts/*
|
node-version: lts/*
|
||||||
|
|
||||||
- uses: actions/cache@v4.2.3
|
- uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # ratchet:actions/cache@v4.3.0
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: ~/.npm
|
path: ~/.npm
|
||||||
|
|||||||
28
AGENTS.md
Normal file
28
AGENTS.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Agent Guidelines for awesome-docker
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
- Build website: `npm run build` (converts README.md to website/index.html)
|
||||||
|
- Test all links: `npm test` (runs tests/test_all.mjs, requires GITHUB_TOKEN)
|
||||||
|
- Test PR changes: `npm run test-pr` (runs tests/pull_request.mjs, checks duplicates)
|
||||||
|
- Health check: `npm run health-check` (generates HEALTH_REPORT.md, requires GITHUB_TOKEN)
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
- **Main content**: README.md - curated list of Docker resources (markdown format)
|
||||||
|
- **Build script**: build.js - converts README.md to HTML using showdown & cheerio
|
||||||
|
- **Tests**: tests/*.mjs - link validation, duplicate detection, URL checking
|
||||||
|
- **Website**: website/ - static site deployment folder
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
- **Language**: Node.js with ES modules (.mjs) for tests, CommonJS for build.js
|
||||||
|
- **Imports**: Use ES6 imports in .mjs files, require() in .js files
|
||||||
|
- **Error handling**: Use try/catch with LOG.error() and process.exit(1) for failures
|
||||||
|
- **Logging**: Use LOG object with error/debug methods (see build.js for pattern)
|
||||||
|
- **Async**: Prefer async/await over callbacks
|
||||||
|
|
||||||
|
## Content Guidelines (from CONTRIBUTING.md)
|
||||||
|
- Link to GitHub projects, not websites
|
||||||
|
- Entries are listed alphabetically (from A to Z)
|
||||||
|
- Entries must be Docker/container-related with clear documentation
|
||||||
|
- Include project description, installation, and usage examples
|
||||||
|
- Mark WIP projects explicitly
|
||||||
|
- Avoid outdated tutorials/blog posts unless advanced/specific
|
||||||
13
README.md
13
README.md
@@ -1,4 +1,4 @@
|
|||||||
# Awesome Docker [][sindresorhus] [](https://app.netlify.com/sites/awesome-docker/deploys)<!-- omit in toc -->
|
# Awesome Docker [][sindresorhus] [](https://app.netlify.com/sites/awesome-docker/deploys)[](https://www.trackawesomelist.com/veggiemonk/awesome-docker/)[](https://github.com/veggiemonk/awesome-docker/commits/main)<!-- omit in toc -->
|
||||||
|
|
||||||
> A curated list of Docker resources and projects
|
> A curated list of Docker resources and projects
|
||||||
|
|
||||||
@@ -100,17 +100,16 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/)
|
|||||||
- [Docker Documentation](https://docs.docker.com/): the official documentation.
|
- [Docker Documentation](https://docs.docker.com/): the official documentation.
|
||||||
- [Docker for beginners](https://github.com/groda/big_data/blob/master/docker_for_beginners.md): A tutorial for beginners who need to learn the basics of Docker—from "Hello world!" to basic interactions with containers, with simple explanations of the underlying concepts.
|
- [Docker for beginners](https://github.com/groda/big_data/blob/master/docker_for_beginners.md): A tutorial for beginners who need to learn the basics of Docker—from "Hello world!" to basic interactions with containers, with simple explanations of the underlying concepts.
|
||||||
- [Docker for novices](https://www.youtube.com/watch?v=xsjSadjKXns) An introduction to Docker for developers and testers who have never used it. (Video 1h40, recorded linux.conf.au 2019 — Christchurch, New Zealand) by Alex Clews.
|
- [Docker for novices](https://www.youtube.com/watch?v=xsjSadjKXns) An introduction to Docker for developers and testers who have never used it. (Video 1h40, recorded linux.conf.au 2019 — Christchurch, New Zealand) by Alex Clews.
|
||||||
- [Docker Hands-on Labs](https://labex.io/learn/docker) A structured Docker skill tree with 100 beginner-friendly hands-on labs by LabEx.
|
|
||||||
- [Docker katas](https://github.com/eficode-academy/docker-katas) A series of labs that will take you from "Hello Docker" to deploying a containerized web application to a server.
|
- [Docker katas](https://github.com/eficode-academy/docker-katas) A series of labs that will take you from "Hello Docker" to deploying a containerized web application to a server.
|
||||||
- [Docker simplified in 55 seconds](https://www.youtube.com/watch?v=vP_4DlOH1G4): An animated high-level introduction to Docker. Think of it as a visual tl;dr that makes it easier to dive into more complex learning materials.
|
- [Docker simplified in 55 seconds](https://www.youtube.com/watch?v=vP_4DlOH1G4): An animated high-level introduction to Docker. Think of it as a visual tl;dr that makes it easier to dive into more complex learning materials.
|
||||||
- [Docker Training](https://training.mirantis.com) :heavy_dollar_sign:
|
- [Docker Training](https://training.mirantis.com) :heavy_dollar_sign:
|
||||||
- [Docker Tutorial for Beginners (Updated 2019 version)](https://hashnode.com/post/docker-tutorial-for-beginners-cjrj2hg5001s2ufs1nker9he2) —In this Docker tutorial, you'll learn all the basics and learn how you can containerize Node.js and Go applications. Even if you aren't familiar with these languages it should be easy for you to follow this tutorial and use any other language.
|
|
||||||
- [Introduction à Docker](https://blog.stephane-robert.info/docs/conteneurs/moteurs-conteneurs/docker/) A dedicated section to master Docker on a French site about DevSecOps: From the basics to best practices, including optimizing, securing your containers...
|
- [Introduction à Docker](https://blog.stephane-robert.info/docs/conteneurs/moteurs-conteneurs/docker/) A dedicated section to master Docker on a French site about DevSecOps: From the basics to best practices, including optimizing, securing your containers...
|
||||||
- [Learn Docker](https://github.com/dwyl/learn-docker): step-by-step tutorial and more resources (video, articles, cheat sheets) by [@dwyl](https://github.com/dwyl)
|
- [Learn Docker](https://github.com/dwyl/learn-docker): step-by-step tutorial and more resources (video, articles, cheat sheets) by [@dwyl](https://github.com/dwyl)
|
||||||
- [Learn Docker (Visually)](https://pagertree.com/learn/docker/overview) - A beginner-focused high-level overview of all the major components of Docker and how they fit together. Lots of high-quality images, examples, and resources.
|
- [Learn Docker (Visually)](https://pagertree.com/learn/docker/overview) - A beginner-focused high-level overview of all the major components of Docker and how they fit together. Lots of high-quality images, examples, and resources.
|
||||||
- [Play With Docker](https://training.play-with-docker.com/): PWD is a great way to get started with Docker from beginner to advanced users. Docker runs directly in your browser.
|
- [Play With Docker](https://training.play-with-docker.com/): PWD is a great way to get started with Docker from beginner to advanced users. Docker runs directly in your browser.
|
||||||
- [Practical Guide about Docker Commands in Spanish](https://github.com/brunocascio/docker-espanol) This Spanish guide contains the use of basic docker commands with real life examples.
|
- [Practical Guide about Docker Commands in Spanish](https://github.com/brunocascio/docker-espanol) This Spanish guide contains the use of basic docker commands with real life examples.
|
||||||
- [Practical Introduction to Container Terminology](https://developers.redhat.com/blog/2018/02/22/container-terminology-practical-introduction) The landscape for container technologies is larger than just docker. Without a good handle on the terminology, It can be difficult to grasp the key differences between docker and (pick your favorites, CRI-O, rkt, lxc/lxd) or understand what the Open Container Initiative is doing to standardize container technology.
|
|
||||||
- [Setting Python Development Environment with VScode and Docker](https://github.com/RamiKrispin/vscode-python): A step-by-step tutorial for setting up a dockerized Python development environment with VScode, Docker, and the Dev Container extension.
|
- [Setting Python Development Environment with VScode and Docker](https://github.com/RamiKrispin/vscode-python): A step-by-step tutorial for setting up a dockerized Python development environment with VScode, Docker, and the Dev Container extension.
|
||||||
- [The Docker Handbook](https://docker-handbook.farhan.dev/) An open-source book that teaches you the fundamentals, best practices and some intermediate Docker functionalities. The book is hosted on [fhsinchy/the-docker-handbook](https://github.com/fhsinchy/the-docker-handbook) and the projects are hosted on [fhsinchy/docker-handbook-projects](https://github.com/fhsinchy/docker-handbook-projects) repository.
|
- [The Docker Handbook](https://docker-handbook.farhan.dev/) An open-source book that teaches you the fundamentals, best practices and some intermediate Docker functionalities. The book is hosted on [fhsinchy/the-docker-handbook](https://github.com/fhsinchy/the-docker-handbook) and the projects are hosted on [fhsinchy/docker-handbook-projects](https://github.com/fhsinchy/docker-handbook-projects) repository.
|
||||||
|
|
||||||
@@ -124,7 +123,6 @@ _Source:_ [What is Docker](https://www.docker.com/why-docker/)
|
|||||||
|
|
||||||
# Where to start (Windows)
|
# Where to start (Windows)
|
||||||
|
|
||||||
- [A Comparative Study of Docker Engine on Windows Server vs Linux Platform](https://collabnix.com/a-comparative-study-of-docker-engine-on-windows-server-vs-linux-platform/) Comparing the feature sets and implementations of Docker on Windows and Linux
|
|
||||||
- [Docker on Windows behind a firewall](https://toedter.com/2015/05/11/docker-on-windows-behind-a-firewall/) by [@kaitoedter](https://twitter.com/kaitoedter)
|
- [Docker on Windows behind a firewall](https://toedter.com/2015/05/11/docker-on-windows-behind-a-firewall/) by [@kaitoedter](https://twitter.com/kaitoedter)
|
||||||
- [Docker Reference Architecture: Modernizing Traditional .NET Framework Applications](https://docs.mirantis.com/containers/v3.0/dockeree-ref-arch/app-dev/modernize-dotnet-apps.html) - You will learn to identify the types of .NET Framework applications that are good candidates for containerization, the "lift-and-shift" approach to containerization.
|
- [Docker Reference Architecture: Modernizing Traditional .NET Framework Applications](https://docs.mirantis.com/containers/v3.0/dockeree-ref-arch/app-dev/modernize-dotnet-apps.html) - You will learn to identify the types of .NET Framework applications that are good candidates for containerization, the "lift-and-shift" approach to containerization.
|
||||||
- [Docker with Microsoft SQL 2016 + ASP.NET](https://blog.alexellis.io/docker-does-sql2016-aspnet/) Demonstration running ASP.NET and SQL Server workloads in Docker
|
- [Docker with Microsoft SQL 2016 + ASP.NET](https://blog.alexellis.io/docker-does-sql2016-aspnet/) Demonstration running ASP.NET and SQL Server workloads in Docker
|
||||||
@@ -395,7 +393,7 @@ Native desktop applications for managing and monitoring docker hosts and cluster
|
|||||||
- [goManageDocker](https://github.com/ajayd-san/gomanagedocker) - TUI tool to view and manage your docker objects blazingly fast with sensible keybindings, also supports VIM navigation out of the box by [@ajay-dsan](https://github.com/ajayd-san)
|
- [goManageDocker](https://github.com/ajayd-san/gomanagedocker) - TUI tool to view and manage your docker objects blazingly fast with sensible keybindings, also supports VIM navigation out of the box by [@ajay-dsan](https://github.com/ajayd-san)
|
||||||
- [lazydocker](https://github.com/jesseduffield/lazydocker) - The lazier way to manage everything docker. A simple terminal UI for both docker and docker-compose, written in Go with the gocui library. By [@jesseduffield](https://github.com/jesseduffield)
|
- [lazydocker](https://github.com/jesseduffield/lazydocker) - The lazier way to manage everything docker. A simple terminal UI for both docker and docker-compose, written in Go with the gocui library. By [@jesseduffield](https://github.com/jesseduffield)
|
||||||
- [lazyjournal](https://github.com/Lifailon/lazyjournal) - A interface for reading and filtering the logs output of Docker and Podman containers like [Dozzle](dozzle) but for the terminal with support for fuzzy find, regex and output coloring
|
- [lazyjournal](https://github.com/Lifailon/lazyjournal) - A interface for reading and filtering the logs output of Docker and Podman containers like [Dozzle](dozzle) but for the terminal with support for fuzzy find, regex and output coloring
|
||||||
- [oxker](https://github.com/mrjackwills/oxker) - A simple tui to view & control docker containers. Written in [Rust](https://www.rust-lang.org/), making heavy use of [ratatui](https://github.com/tui-rs-revival/ratatui) & [Bollard](https://github.com/fussybeaver/bollard), by [@mrjackwills](https://github.com/mrjackwills)
|
- [oxker](https://github.com/mrjackwills/oxker) - A simple tui to view & control docker containers. Written in [Rust](https://rust-lang.org/), making heavy use of [ratatui](https://github.com/tui-rs-revival/ratatui) & [Bollard](https://github.com/fussybeaver/bollard), by [@mrjackwills](https://github.com/mrjackwills)
|
||||||
- [sen](https://github.com/TomasTomecek/sen) - :skull: Terminal user interface for docker engine, by [@TomasTomecek][tomastomecek]
|
- [sen](https://github.com/TomasTomecek/sen) - :skull: Terminal user interface for docker engine, by [@TomasTomecek][tomastomecek]
|
||||||
|
|
||||||
##### CLI tools
|
##### CLI tools
|
||||||
@@ -745,7 +743,6 @@ Services to securely store your Docker images.
|
|||||||
- [Giant Swarm](https://www.giantswarm.io/) :heavy_dollar_sign: - Simple microservice infrastructure. Deploy your containers in seconds.
|
- [Giant Swarm](https://www.giantswarm.io/) :heavy_dollar_sign: - Simple microservice infrastructure. Deploy your containers in seconds.
|
||||||
- [Google Container Engine](https://cloud.google.com/kubernetes-engine/docs/) :heavy_dollar_sign: - Docker containers on Google Cloud Computing powered by [Kubernetes][kubernetes].
|
- [Google Container Engine](https://cloud.google.com/kubernetes-engine/docs/) :heavy_dollar_sign: - Docker containers on Google Cloud Computing powered by [Kubernetes][kubernetes].
|
||||||
- [Mesosphere DC/OS Platform](https://d2iq.com/products/dcos) :heavy_dollar_sign: - Integrated platform for data and containers built on Apache Mesos by [@mesosphere](https://d2iq.com)
|
- [Mesosphere DC/OS Platform](https://d2iq.com/products/dcos) :heavy_dollar_sign: - Integrated platform for data and containers built on Apache Mesos by [@mesosphere](https://d2iq.com)
|
||||||
- [Red Hat CodeReady Workspaces](https://developers.redhat.com/products/openshift-dev-spaces/overview) - A collaborative Kubernetes-native solution for rapid application development that delivers consistent developer environments on Red Hat OpenShift to allow anyone with a browser to contribute code in under two minutes.
|
|
||||||
- [Red Hat OpenShift Dedicated](https://www.redhat.com/en/technologies/cloud-computing/openshift/dedicated) :heavy_dollar_sign: - Fully-managed Red Hat® OpenShift® service on Amazon Web Services and Google Cloud
|
- [Red Hat OpenShift Dedicated](https://www.redhat.com/en/technologies/cloud-computing/openshift/dedicated) :heavy_dollar_sign: - Fully-managed Red Hat® OpenShift® service on Amazon Web Services and Google Cloud
|
||||||
- [Triton](https://www.joyent.com/) :heavy_dollar_sign: - Elastic container-native infrastructure by Joyent.
|
- [Triton](https://www.joyent.com/) :heavy_dollar_sign: - Elastic container-native infrastructure by Joyent.
|
||||||
- [Virtuozzo Application Platform](https://www.virtuozzo.com/application-platform-partners/) :heavy_dollar_sign: - Deploy and manage your projects with turnkey PaaS across a wide network of reliable service providers
|
- [Virtuozzo Application Platform](https://www.virtuozzo.com/application-platform-partners/) :heavy_dollar_sign: - Deploy and manage your projects with turnkey PaaS across a wide network of reliable service providers
|
||||||
@@ -769,7 +766,7 @@ Services to securely store your Docker images.
|
|||||||
- [Cloud Native Landscape](https://github.com/cncf/landscape)
|
- [Cloud Native Landscape](https://github.com/cncf/landscape)
|
||||||
- [Docker Blog](https://www.docker.com/blog/) - regular updates about Docker, the community and tools
|
- [Docker Blog](https://www.docker.com/blog/) - regular updates about Docker, the community and tools
|
||||||
- [Docker Certification](https://intellipaat.com/docker-training-course/?US) :heavy_dollar_sign: will help you to will Learn Docker containerization, running Docker containers, Image creation, Dockerfile, Docker orchestration, security best practices, and more through hands-on projects and case studies and helps to clear Docker Certified Associate.
|
- [Docker Certification](https://intellipaat.com/docker-training-course/?US) :heavy_dollar_sign: will help you to will Learn Docker containerization, running Docker containers, Image creation, Dockerfile, Docker orchestration, security best practices, and more through hands-on projects and case studies and helps to clear Docker Certified Associate.
|
||||||
- [Docker Community on Hashnode](https://hashnode.com/n/docker)
|
|
||||||
- [Docker dev bookmarks](https://www.codever.dev/search?q=docker) - use the tag [docker](https://www.codever.dev/bookmarks/t/docker)
|
- [Docker dev bookmarks](https://www.codever.dev/search?q=docker) - use the tag [docker](https://www.codever.dev/bookmarks/t/docker)
|
||||||
- [Docker in Action, Second Edition](https://www.manning.com/books/docker-in-action-second-edition)
|
- [Docker in Action, Second Edition](https://www.manning.com/books/docker-in-action-second-edition)
|
||||||
- [Docker in Practice, Second Edition](https://www.manning.com/books/docker-in-practice-second-edition)
|
- [Docker in Practice, Second Edition](https://www.manning.com/books/docker-in-practice-second-edition)
|
||||||
|
|||||||
852
package-lock.json
generated
852
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rimraf ./dist/ && node build.js",
|
"build": "rimraf ./dist/ && node build.js",
|
||||||
"test-pr": "node tests/pull_request.mjs",
|
"test-pr": "node tests/pull_request.mjs",
|
||||||
"test": "node tests/test_all.mjs"
|
"test": "node tests/test_all.mjs",
|
||||||
|
"health-check": "node tests/health_check.mjs"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ const LINKS_OPTIONS = {
|
|||||||
'user-agent':
|
'user-agent':
|
||||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
|
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
|
||||||
},
|
},
|
||||||
|
timeout: 60000, // 1m
|
||||||
|
signal: AbortSignal.timeout(60000),
|
||||||
};
|
};
|
||||||
|
|
||||||
const LOG = {
|
const LOG = {
|
||||||
|
|||||||
@@ -10,5 +10,8 @@
|
|||||||
"https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg",
|
"https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg",
|
||||||
"https://www.se-radio.net/2017/05/se-radio-episode-290-diogo-monica-on-docker-security",
|
"https://www.se-radio.net/2017/05/se-radio-episode-290-diogo-monica-on-docker-security",
|
||||||
"https://www.reddit.com/r/docker/",
|
"https://www.reddit.com/r/docker/",
|
||||||
"https://www.udacity.com/course/scalable-microservices-with-kubernetes--ud615"
|
"https://www.udacity.com/course/scalable-microservices-with-kubernetes--ud615",
|
||||||
|
"https://www.youtube.com/playlist",
|
||||||
|
"https://www.aquasec.com",
|
||||||
|
"https://cloudsmith.com"
|
||||||
]
|
]
|
||||||
|
|||||||
206
tests/health_check.mjs
Normal file
206
tests/health_check.mjs
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
import fs from 'fs-extra';
|
||||||
|
import fetch from 'node-fetch';
|
||||||
|
import helper from './common.mjs';
|
||||||
|
|
||||||
|
const README = 'README.md';
|
||||||
|
const GITHUB_GQL_API = 'https://api.github.com/graphql';
|
||||||
|
const TOKEN = process.env.GITHUB_TOKEN || '';
|
||||||
|
|
||||||
|
if (!TOKEN) {
|
||||||
|
console.error('GITHUB_TOKEN environment variable is required');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Authorization = `token ${TOKEN}`;
|
||||||
|
|
||||||
|
const LOG = {
|
||||||
|
info: (...args) => console.log('ℹ️ ', ...args),
|
||||||
|
warn: (...args) => console.warn('⚠️ ', ...args),
|
||||||
|
error: (...args) => console.error('❌', ...args),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Extract GitHub repos from links
|
||||||
|
const extract_repos = (arr) =>
|
||||||
|
arr
|
||||||
|
.map((e) => e.substr('https://github.com/'.length).split('/'))
|
||||||
|
.filter((r) => r.length === 2 && r[1] !== '');
|
||||||
|
|
||||||
|
// Generate GraphQL query to check repo health
|
||||||
|
const generate_health_query = (repos) => {
|
||||||
|
const repoQueries = repos.map(([owner, name]) => {
|
||||||
|
const safeName = `repo_${owner.replace(/(-|\.)/g, '_')}_${name.replace(/(-|\.)/g, '_')}`;
|
||||||
|
return `${safeName}: repository(owner: "${owner}", name:"${name}"){
|
||||||
|
nameWithOwner
|
||||||
|
isArchived
|
||||||
|
pushedAt
|
||||||
|
createdAt
|
||||||
|
stargazerCount
|
||||||
|
forkCount
|
||||||
|
isDisabled
|
||||||
|
isFork
|
||||||
|
isLocked
|
||||||
|
isPrivate
|
||||||
|
}`;
|
||||||
|
}).join('\n');
|
||||||
|
|
||||||
|
return `query REPO_HEALTH { ${repoQueries} }`;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Batch repos into smaller chunks for GraphQL
|
||||||
|
function* batchRepos(repos, size = 50) {
|
||||||
|
for (let i = 0; i < repos.length; i += size) {
|
||||||
|
yield repos.slice(i, i + size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function checkRepoHealth(repos) {
|
||||||
|
const results = {
|
||||||
|
archived: [],
|
||||||
|
stale: [], // No commits in 2+ years
|
||||||
|
inactive: [], // No commits in 1-2 years
|
||||||
|
healthy: [],
|
||||||
|
disabled: [],
|
||||||
|
total: repos.length,
|
||||||
|
};
|
||||||
|
|
||||||
|
const twoYearsAgo = new Date();
|
||||||
|
twoYearsAgo.setFullYear(twoYearsAgo.getFullYear() - 2);
|
||||||
|
|
||||||
|
const oneYearAgo = new Date();
|
||||||
|
oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);
|
||||||
|
|
||||||
|
LOG.info(`Checking health of ${repos.length} repositories...`);
|
||||||
|
|
||||||
|
for (const batch of batchRepos(repos)) {
|
||||||
|
const query = generate_health_query(batch);
|
||||||
|
const options = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Authorization,
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ query }),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(GITHUB_GQL_API, options);
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (data.errors) {
|
||||||
|
LOG.error('GraphQL errors:', data.errors);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, repo] of Object.entries(data.data)) {
|
||||||
|
if (!repo) continue;
|
||||||
|
|
||||||
|
const pushedAt = new Date(repo.pushedAt);
|
||||||
|
const repoInfo = {
|
||||||
|
name: repo.nameWithOwner,
|
||||||
|
pushedAt: repo.pushedAt,
|
||||||
|
stars: repo.stargazerCount,
|
||||||
|
url: `https://github.com/${repo.nameWithOwner}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (repo.isArchived) {
|
||||||
|
results.archived.push(repoInfo);
|
||||||
|
} else if (repo.isDisabled) {
|
||||||
|
results.disabled.push(repoInfo);
|
||||||
|
} else if (pushedAt < twoYearsAgo) {
|
||||||
|
results.stale.push(repoInfo);
|
||||||
|
} else if (pushedAt < oneYearAgo) {
|
||||||
|
results.inactive.push(repoInfo);
|
||||||
|
} else {
|
||||||
|
results.healthy.push(repoInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
LOG.error('Batch fetch error:', error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rate limiting - wait a bit between batches
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateReport(results) {
|
||||||
|
const report = [];
|
||||||
|
|
||||||
|
report.push('# 🏥 Awesome Docker - Health Check Report\n');
|
||||||
|
report.push(`**Generated:** ${new Date().toISOString()}\n`);
|
||||||
|
report.push(`**Total Repositories:** ${results.total}\n`);
|
||||||
|
|
||||||
|
report.push('\n## 📊 Summary\n');
|
||||||
|
report.push(`- ✅ Healthy (updated in last year): ${results.healthy.length}`);
|
||||||
|
report.push(`- ⚠️ Inactive (1-2 years): ${results.inactive.length}`);
|
||||||
|
report.push(`- 🪦 Stale (2+ years): ${results.stale.length}`);
|
||||||
|
report.push(`- 📦 Archived: ${results.archived.length}`);
|
||||||
|
report.push(`- 🚫 Disabled: ${results.disabled.length}\n`);
|
||||||
|
|
||||||
|
if (results.archived.length > 0) {
|
||||||
|
report.push('\n## 📦 Archived Repositories (Should mark as :skull:)\n');
|
||||||
|
results.archived.forEach(repo => {
|
||||||
|
report.push(`- [${repo.name}](${repo.url}) - ⭐ ${repo.stars} - Last push: ${repo.pushedAt}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.stale.length > 0) {
|
||||||
|
report.push('\n## 🪦 Stale Repositories (No activity in 2+ years)\n');
|
||||||
|
results.stale.slice(0, 50).forEach(repo => {
|
||||||
|
report.push(`- [${repo.name}](${repo.url}) - ⭐ ${repo.stars} - Last push: ${repo.pushedAt}`);
|
||||||
|
});
|
||||||
|
if (results.stale.length > 50) {
|
||||||
|
report.push(`\n... and ${results.stale.length - 50} more`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.inactive.length > 0) {
|
||||||
|
report.push('\n## ⚠️ Inactive Repositories (No activity in 1-2 years)\n');
|
||||||
|
report.push('_These may still be stable/complete projects - review individually_\n');
|
||||||
|
results.inactive.slice(0, 30).forEach(repo => {
|
||||||
|
report.push(`- [${repo.name}](${repo.url}) - ⭐ ${repo.stars} - Last push: ${repo.pushedAt}`);
|
||||||
|
});
|
||||||
|
if (results.inactive.length > 30) {
|
||||||
|
report.push(`\n... and ${results.inactive.length - 30} more`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return report.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const markdown = await fs.readFile(README, 'utf8');
|
||||||
|
let links = helper.extract_all_links(markdown);
|
||||||
|
|
||||||
|
const github_links = links.filter(link =>
|
||||||
|
link.startsWith('https://github.com') &&
|
||||||
|
!helper.exclude_from_list(link) &&
|
||||||
|
!link.includes('/issues') &&
|
||||||
|
!link.includes('/pull') &&
|
||||||
|
!link.includes('/wiki') &&
|
||||||
|
!link.includes('#')
|
||||||
|
);
|
||||||
|
|
||||||
|
const repos = extract_repos(github_links);
|
||||||
|
const results = await checkRepoHealth(repos);
|
||||||
|
|
||||||
|
const report = generateReport(results);
|
||||||
|
|
||||||
|
// Save report
|
||||||
|
await fs.writeFile('HEALTH_REPORT.md', report);
|
||||||
|
LOG.info('Health report saved to HEALTH_REPORT.md');
|
||||||
|
|
||||||
|
// Also print summary to console
|
||||||
|
console.log('\n' + report);
|
||||||
|
|
||||||
|
// Exit with error if there are actionable items
|
||||||
|
if (results.archived.length > 0 || results.stale.length > 10) {
|
||||||
|
LOG.warn(`Found ${results.archived.length} archived and ${results.stale.length} stale repos`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Starting health check...');
|
||||||
|
main();
|
||||||
@@ -63,4 +63,7 @@ async function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log('starting...');
|
console.log('starting...');
|
||||||
main();
|
main().catch((error) => {
|
||||||
|
console.error('Fatal error:', error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ const generate_GQL_query = (arr) =>
|
|||||||
`repo_${owner.replace(/(-|\.)/g, '_')}_${name.replace(
|
`repo_${owner.replace(/(-|\.)/g, '_')}_${name.replace(
|
||||||
/(-|\.)/g,
|
/(-|\.)/g,
|
||||||
'_',
|
'_',
|
||||||
)}: repository(owner: "${owner}", name:"${name}"){ nameWithOwner } `,
|
)}: repository(owner: "${owner}", name:"${name}"){ nameWithOwner isArchived } `,
|
||||||
)
|
)
|
||||||
.join('')} }`;
|
.join('')} }`;
|
||||||
|
|
||||||
@@ -95,6 +95,22 @@ async function main() {
|
|||||||
has_error.github_repos = gql_response.errors;
|
has_error.github_repos = gql_response.errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for archived repositories
|
||||||
|
console.log('checking for archived repositories...');
|
||||||
|
const archived_repos = [];
|
||||||
|
if (gql_response.data) {
|
||||||
|
for (const [key, repo] of Object.entries(gql_response.data)) {
|
||||||
|
if (repo && repo.isArchived) {
|
||||||
|
archived_repos.push(repo.nameWithOwner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (archived_repos.length > 0) {
|
||||||
|
console.warn(`⚠️ Found ${archived_repos.length} archived repositories that should be marked with :skull:`);
|
||||||
|
console.warn('Archived repos:', archived_repos);
|
||||||
|
// Don't fail the build, just warn
|
||||||
|
}
|
||||||
|
|
||||||
console.log({
|
console.log({
|
||||||
TEST_PASSED: has_error.show,
|
TEST_PASSED: has_error.show,
|
||||||
GITHUB_REPOSITORY: github_links.length,
|
GITHUB_REPOSITORY: github_links.length,
|
||||||
|
|||||||
Reference in New Issue
Block a user