fix: workflows
This commit is contained in:
188
.github/workflows/README.md
vendored
Normal file
188
.github/workflows/README.md
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
# GitHub Actions Workflows
|
||||
|
||||
This directory contains automated workflows for building, testing, and deploying the awesome-app.
|
||||
|
||||
## Workflows
|
||||
|
||||
### 1. `db.yml` - Build Awesome Database
|
||||
|
||||
**Triggers:**
|
||||
- Schedule: Every 6 hours
|
||||
- Manual: `workflow_dispatch`
|
||||
- Push to main (when db.yml or build-db.js changes)
|
||||
|
||||
**Purpose:**
|
||||
Builds the SQLite database by scraping awesome lists from GitHub.
|
||||
|
||||
**Artifacts:**
|
||||
- `awesome.db` - SQLite database file
|
||||
- `db-metadata.json` - Metadata about the build (timestamp, hash, counts)
|
||||
|
||||
**Retention:** 90 days
|
||||
|
||||
---
|
||||
|
||||
### 2. `docker-publish.yml` - Build and Push Docker Image
|
||||
|
||||
**Triggers:**
|
||||
- Push to `main` or `develop` branches
|
||||
- Git tags matching `v*.*.*`
|
||||
- Pull requests to `main`
|
||||
- Manual: `workflow_dispatch`
|
||||
|
||||
**Dependencies:**
|
||||
- Calls `db.yml` workflow first
|
||||
- Downloads database artifact before building Docker image
|
||||
|
||||
**Features:**
|
||||
- Multi-platform builds (linux/amd64, linux/arm64)
|
||||
- Automatic semantic versioning from git tags
|
||||
- GitHub Container Registry (ghcr.io)
|
||||
- Build cache optimization
|
||||
- Database metadata embedded in image labels
|
||||
- Configurable database inclusion via `INCLUDE_DATABASE` build arg (default: `true` in CI)
|
||||
|
||||
**Image Tags:**
|
||||
- `latest` - Latest build from main branch
|
||||
- `main` - Latest main branch build
|
||||
- `develop` - Latest develop branch build
|
||||
- `v1.2.3` - Semantic version tags
|
||||
- `main-abc1234` - Branch + commit SHA
|
||||
|
||||
**Image Labels:**
|
||||
- Standard OCI labels (title, description, vendor, source)
|
||||
- Database metadata (timestamp, hash, counts)
|
||||
|
||||
---
|
||||
|
||||
### 3. `docker-scan.yml` - Security Scanning
|
||||
|
||||
**Triggers:**
|
||||
- Schedule: Daily at 2 AM UTC
|
||||
- Push to `main` branch
|
||||
- Git tags matching `v*.*.*`
|
||||
- Manual: `workflow_dispatch`
|
||||
|
||||
**Purpose:**
|
||||
Scans Docker images for security vulnerabilities using Trivy.
|
||||
|
||||
**Features:**
|
||||
- SARIF report upload to GitHub Security tab
|
||||
- Scans for CRITICAL, HIGH, and MEDIUM severity issues
|
||||
- Automated daily security checks
|
||||
|
||||
---
|
||||
|
||||
### 4. `cleanup-images.yml` - Cleanup Old Docker Images
|
||||
|
||||
**Triggers:**
|
||||
- Schedule: Weekly on Sundays at 3 AM UTC
|
||||
- Manual: `workflow_dispatch` (configurable retention count)
|
||||
|
||||
**Purpose:**
|
||||
Removes old untagged Docker images to save storage.
|
||||
|
||||
**Configuration:**
|
||||
- Default: Keep 10 most recent versions
|
||||
- Configurable via workflow_dispatch input
|
||||
|
||||
---
|
||||
|
||||
## Workflow Integration
|
||||
|
||||
The workflows are designed to work together:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[db.yml] --> B[docker-publish.yml]
|
||||
B --> C[docker-scan.yml]
|
||||
D[cleanup-images.yml]
|
||||
```
|
||||
|
||||
1. **Database Build** (`db.yml`) runs every 6 hours and on-demand
|
||||
2. **Docker Build** (`docker-publish.yml`) depends on database build
|
||||
3. **Security Scan** (`docker-scan.yml`) runs after image push
|
||||
4. **Cleanup** (`cleanup-images.yml`) runs weekly to free storage
|
||||
|
||||
## Usage
|
||||
|
||||
### Manual Database Build
|
||||
|
||||
```bash
|
||||
gh workflow run db.yml
|
||||
```
|
||||
|
||||
### Manual Docker Build
|
||||
|
||||
```bash
|
||||
gh workflow run docker-publish.yml -f tag=custom-tag
|
||||
```
|
||||
|
||||
### Manual Security Scan
|
||||
|
||||
```bash
|
||||
gh workflow run docker-scan.yml
|
||||
```
|
||||
|
||||
### Manual Cleanup
|
||||
|
||||
```bash
|
||||
gh workflow run cleanup-images.yml -f keep_count=20
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Required repository secrets:
|
||||
- `GITHUB_TOKEN` - Automatically provided
|
||||
- `WEBHOOK_URL` - (Optional) Webhook for database updates
|
||||
- `WEBHOOK_SECRET` - (Optional) Secret for webhook authentication
|
||||
|
||||
## Docker Image
|
||||
|
||||
Pull the latest image:
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/valknarness/awesome-app:latest
|
||||
```
|
||||
|
||||
Run with embedded database (CI builds):
|
||||
|
||||
```bash
|
||||
docker run -p 3000:3000 ghcr.io/valknarness/awesome-app:latest
|
||||
```
|
||||
|
||||
Run with volume-mounted database (local builds):
|
||||
|
||||
```bash
|
||||
docker run -p 3000:3000 -v $(pwd)/data:/app/data ghcr.io/valknarness/awesome-app:latest
|
||||
```
|
||||
|
||||
### Build Arguments
|
||||
|
||||
Control database inclusion when building locally:
|
||||
|
||||
```bash
|
||||
# Include database in image (like CI)
|
||||
docker build --build-arg INCLUDE_DATABASE=true -t awesome-app .
|
||||
|
||||
# Exclude database (mount at runtime)
|
||||
docker build --build-arg INCLUDE_DATABASE=false -t awesome-app .
|
||||
```
|
||||
|
||||
Or with docker-compose:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
awesome-app:
|
||||
build:
|
||||
args:
|
||||
INCLUDE_DATABASE: true # or false
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Database builds** happen automatically every 6 hours
|
||||
2. **Docker images** are built on every push to main/develop
|
||||
3. **Security scans** run daily to catch new vulnerabilities
|
||||
4. **Old images** are cleaned up weekly to save storage
|
||||
5. **Database metadata** is embedded in Docker image labels for traceability
|
||||
9
.github/workflows/db.yml
vendored
9
.github/workflows/db.yml
vendored
@@ -20,14 +20,19 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22'
|
||||
cache: 'npm'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build SQLite Database
|
||||
env:
|
||||
|
||||
37
.github/workflows/docker-publish.yml
vendored
37
.github/workflows/docker-publish.yml
vendored
@@ -22,7 +22,12 @@ env:
|
||||
IMAGE_NAME: valknarness/awesome-app
|
||||
|
||||
jobs:
|
||||
build-database:
|
||||
uses: ./.github/workflows/db.yml
|
||||
secrets: inherit
|
||||
|
||||
build-and-push:
|
||||
needs: build-database
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -33,6 +38,27 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download database artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: awesome-database
|
||||
path: ./
|
||||
|
||||
- name: Verify database artifact
|
||||
run: |
|
||||
ls -lah awesome.db* || echo "No database file found"
|
||||
cat db-metadata.json || echo "No metadata file found"
|
||||
|
||||
- name: Extract database metadata
|
||||
id: db-meta
|
||||
run: |
|
||||
if [ -f db-metadata.json ]; then
|
||||
echo "db_timestamp=$(jq -r '.timestamp' db-metadata.json)" >> $GITHUB_OUTPUT
|
||||
echo "db_hash=$(jq -r '.hash' db-metadata.json)" >> $GITHUB_OUTPUT
|
||||
echo "lists_count=$(jq -r '.lists_count' db-metadata.json)" >> $GITHUB_OUTPUT
|
||||
echo "repos_count=$(jq -r '.repos_count' db-metadata.json)" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
@@ -70,6 +96,10 @@ jobs:
|
||||
org.opencontainers.image.description=Next.js application for exploring awesome lists
|
||||
org.opencontainers.image.vendor=valknarness
|
||||
org.opencontainers.image.source=https://github.com/${{ github.repository }}
|
||||
app.database.timestamp=${{ steps.db-meta.outputs.db_timestamp }}
|
||||
app.database.hash=${{ steps.db-meta.outputs.db_hash }}
|
||||
app.database.lists_count=${{ steps.db-meta.outputs.lists_count }}
|
||||
app.database.repos_count=${{ steps.db-meta.outputs.repos_count }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
@@ -83,6 +113,7 @@ jobs:
|
||||
cache-to: type=gha,mode=max
|
||||
build-args: |
|
||||
NODE_ENV=production
|
||||
INCLUDE_DATABASE=false
|
||||
|
||||
- name: Generate image digest
|
||||
if: github.event_name != 'pull_request'
|
||||
@@ -97,6 +128,12 @@ jobs:
|
||||
echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Database Info:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Built: ${{ steps.db-meta.outputs.db_timestamp }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Lists: ${{ steps.db-meta.outputs.lists_count }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Repositories: ${{ steps.db-meta.outputs.repos_count }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Hash: \`${{ steps.db-meta.outputs.db_hash }}\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Pull command:**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
|
||||
echo "docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
Reference in New Issue
Block a user