- compose.yml: add act-runner service (gitea/act_runner:latest) with Docker socket, registered to Gitea instance - stack.toml: ci.backend = "gitea" (was "woodpecker") - Generated .gitea/workflows/*.yml (6 workflows) - Removed .woodpecker/*.yml (stale backend cleaned) - Gitea Actions secrets: REGISTRY_USER, REGISTRY_TOKEN - yamllint validates all generated workflows (warnings only) act_runner v0.3.0 registered as homelab-runner with ubuntu-latest label. Gitea 1.25.4 has Actions enabled by default. GITEA_TOKEN auto-injected for API calls; PAT-based REGISTRY_TOKEN for container registry pushes.
This commit is contained in:
36
.gitea/workflows/ci.yml
Normal file
36
.gitea/workflows/ci.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
# DO NOT EDIT — generated by gen_config.py from stack.toml
|
||||
# Re-generate: uv run python dev/scripts/gen_config.py
|
||||
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["**"]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
lint-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up uv
|
||||
uses: astral-sh/setup-uv@v4
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Install dependencies
|
||||
run: uv sync --dev
|
||||
|
||||
- name: Ruff check
|
||||
run: uv run ruff check src/ tests/ --output-format=concise
|
||||
|
||||
- name: Ruff format
|
||||
run: uv run ruff format --check src/ tests/
|
||||
|
||||
- name: Pytest
|
||||
run: uv run pytest tests/ --cov=src --cov-report=term-missing --cov-fail-under=99 -q
|
||||
|
||||
- name: Validate generated config
|
||||
run: uv run python dev/scripts/gen_config.py --check
|
||||
146
.gitea/workflows/deploy.yml
Normal file
146
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,146 @@
|
||||
# DO NOT EDIT — generated by gen_config.py from stack.toml
|
||||
# Re-generate: uv run python dev/scripts/gen_config.py
|
||||
|
||||
name: Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to container registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: gitea.homelab.fhirworx.io
|
||||
username: ${{ secrets.REGISTRY_USER }}
|
||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||
|
||||
- name: Compute short SHA
|
||||
run: echo "SHORT_SHA=${{GITHUB_SHA::8}}" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build notebooks
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: notebooks/
|
||||
file: notebooks/Dockerfile
|
||||
push: true
|
||||
tags: gitea.homelab.fhirworx.io/homelab/stack/notebooks:${{ env.SHORT_SHA }},gitea.homelab.fhirworx.io/homelab/stack/notebooks:latest
|
||||
|
||||
- name: Build zotero
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: zotero/
|
||||
file: zotero/Dockerfile
|
||||
push: true
|
||||
tags: gitea.homelab.fhirworx.io/homelab/stack/zotero:${{ env.SHORT_SHA }},gitea.homelab.fhirworx.io/homelab/stack/zotero:latest
|
||||
|
||||
- name: Build docs
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: docs/Dockerfile
|
||||
push: true
|
||||
tags: gitea.homelab.fhirworx.io/homelab/stack/docs:${{ env.SHORT_SHA }},gitea.homelab.fhirworx.io/homelab/stack/docs:latest
|
||||
|
||||
- name: Build api
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: api/Dockerfile
|
||||
push: true
|
||||
tags: gitea.homelab.fhirworx.io/homelab/stack/api:${{ env.SHORT_SHA }},gitea.homelab.fhirworx.io/homelab/stack/api:latest
|
||||
|
||||
- name: Build mc
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: rustfs/
|
||||
file: rustfs/Dockerfile.mc
|
||||
push: true
|
||||
tags: gitea.homelab.fhirworx.io/homelab/stack/mc:${{ env.SHORT_SHA }},gitea.homelab.fhirworx.io/homelab/stack/mc:latest
|
||||
|
||||
scan:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Compute short SHA
|
||||
run: echo "SHORT_SHA=${{GITHUB_SHA::8}}" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Scan notebooks
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: gitea.homelab.fhirworx.io/homelab/stack/notebooks:${{ env.SHORT_SHA }}
|
||||
severity: HIGH,CRITICAL
|
||||
exit-code: "0"
|
||||
format: json
|
||||
output: notebooks-scan.json
|
||||
|
||||
- name: Scan zotero
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: gitea.homelab.fhirworx.io/homelab/stack/zotero:${{ env.SHORT_SHA }}
|
||||
severity: HIGH,CRITICAL
|
||||
exit-code: "0"
|
||||
format: json
|
||||
output: zotero-scan.json
|
||||
|
||||
- name: Scan docs
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: gitea.homelab.fhirworx.io/homelab/stack/docs:${{ env.SHORT_SHA }}
|
||||
severity: HIGH,CRITICAL
|
||||
exit-code: "0"
|
||||
format: json
|
||||
output: docs-scan.json
|
||||
|
||||
- name: Scan api
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: gitea.homelab.fhirworx.io/homelab/stack/api:${{ env.SHORT_SHA }}
|
||||
severity: HIGH,CRITICAL
|
||||
exit-code: "0"
|
||||
format: json
|
||||
output: api-scan.json
|
||||
|
||||
- name: Upload scan results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: trivy-scans
|
||||
path: "*-scan.json"
|
||||
|
||||
report-vulns:
|
||||
runs-on: ubuntu-latest
|
||||
needs: scan
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up uv
|
||||
uses: astral-sh/setup-uv@v4
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Download scan results
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: trivy-scans
|
||||
|
||||
- name: Report vulnerabilities
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
run: |
|
||||
uv sync --no-dev
|
||||
for f in notebooks-scan.json zotero-scan.json docs-scan.json api-scan.json; do
|
||||
[ -f "$f" ] && uv run python -m api.diag.vuln "$f" || true
|
||||
done
|
||||
149
.gitea/workflows/harden.yml
Normal file
149
.gitea/workflows/harden.yml
Normal file
@@ -0,0 +1,149 @@
|
||||
# DO NOT EDIT — generated by gen_config.py from stack.toml
|
||||
# Re-generate: uv run python dev/scripts/gen_config.py
|
||||
|
||||
name: Harden
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 2 * * 0"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to container registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: gitea.homelab.fhirworx.io
|
||||
username: ${{ secrets.REGISTRY_USER }}
|
||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||
|
||||
- name: Build notebooks
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: notebooks/
|
||||
file: notebooks/Dockerfile
|
||||
push: true
|
||||
tags: gitea.homelab.fhirworx.io/homelab/stack/notebooks:hardened,gitea.homelab.fhirworx.io/homelab/stack/notebooks:latest
|
||||
no-cache: true
|
||||
|
||||
- name: Build zotero
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: zotero/
|
||||
file: zotero/Dockerfile
|
||||
push: true
|
||||
tags: gitea.homelab.fhirworx.io/homelab/stack/zotero:hardened,gitea.homelab.fhirworx.io/homelab/stack/zotero:latest
|
||||
no-cache: true
|
||||
|
||||
- name: Build docs
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: docs/Dockerfile
|
||||
push: true
|
||||
tags: gitea.homelab.fhirworx.io/homelab/stack/docs:hardened,gitea.homelab.fhirworx.io/homelab/stack/docs:latest
|
||||
no-cache: true
|
||||
|
||||
- name: Build api
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: api/Dockerfile
|
||||
push: true
|
||||
tags: gitea.homelab.fhirworx.io/homelab/stack/api:hardened,gitea.homelab.fhirworx.io/homelab/stack/api:latest
|
||||
no-cache: true
|
||||
|
||||
- name: Build mc
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: rustfs/
|
||||
file: rustfs/Dockerfile.mc
|
||||
push: true
|
||||
tags: gitea.homelab.fhirworx.io/homelab/stack/mc:hardened,gitea.homelab.fhirworx.io/homelab/stack/mc:latest
|
||||
no-cache: true
|
||||
|
||||
scan:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Scan notebooks
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: gitea.homelab.fhirworx.io/homelab/stack/notebooks:hardened
|
||||
severity: HIGH,CRITICAL
|
||||
exit-code: "0"
|
||||
format: json
|
||||
output: notebooks-scan.json
|
||||
|
||||
- name: Scan zotero
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: gitea.homelab.fhirworx.io/homelab/stack/zotero:hardened
|
||||
severity: HIGH,CRITICAL
|
||||
exit-code: "0"
|
||||
format: json
|
||||
output: zotero-scan.json
|
||||
|
||||
- name: Scan docs
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: gitea.homelab.fhirworx.io/homelab/stack/docs:hardened
|
||||
severity: HIGH,CRITICAL
|
||||
exit-code: "0"
|
||||
format: json
|
||||
output: docs-scan.json
|
||||
|
||||
- name: Scan api
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: gitea.homelab.fhirworx.io/homelab/stack/api:hardened
|
||||
severity: HIGH,CRITICAL
|
||||
exit-code: "0"
|
||||
format: json
|
||||
output: api-scan.json
|
||||
|
||||
- name: Upload scan results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: trivy-scans-harden
|
||||
path: "*-scan.json"
|
||||
|
||||
close-or-report-vulns:
|
||||
runs-on: ubuntu-latest
|
||||
needs: scan
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up uv
|
||||
uses: astral-sh/setup-uv@v4
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Download scan results
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: trivy-scans-harden
|
||||
|
||||
- name: Close resolved or file new vuln issues
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
run: |
|
||||
uv sync --no-dev
|
||||
for f in notebooks-scan.json zotero-scan.json docs-scan.json api-scan.json; do
|
||||
if [ -f "$f" ]; then
|
||||
uv run python -m api.diag.vuln --close "$f" || \
|
||||
uv run python -m api.diag.vuln "$f" || true
|
||||
fi
|
||||
done
|
||||
140
.gitea/workflows/infra-ci.yml
Normal file
140
.gitea/workflows/infra-ci.yml
Normal file
@@ -0,0 +1,140 @@
|
||||
# DO NOT EDIT — generated by gen_config.py from stack.toml
|
||||
# Re-generate: uv run python dev/scripts/gen_config.py
|
||||
|
||||
name: Infra CI
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'notebooks/**'
|
||||
- 'zotero/**'
|
||||
- 'docs/**'
|
||||
- 'api/**'
|
||||
- 'src/**'
|
||||
- 'pyproject.toml'
|
||||
- 'rustfs/**'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'notebooks/**'
|
||||
- 'zotero/**'
|
||||
- 'docs/**'
|
||||
- 'api/**'
|
||||
- 'src/**'
|
||||
- 'pyproject.toml'
|
||||
- 'rustfs/**'
|
||||
|
||||
jobs:
|
||||
notebooks:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Hadolint notebooks
|
||||
uses: hadolint/hadolint-action@v3.1.0
|
||||
with:
|
||||
dockerfile: notebooks/Dockerfile
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build notebooks
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: notebooks/
|
||||
file: notebooks/Dockerfile
|
||||
push: false
|
||||
tags: ci-test-notebooks
|
||||
load: true
|
||||
|
||||
zotero:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Hadolint zotero
|
||||
uses: hadolint/hadolint-action@v3.1.0
|
||||
with:
|
||||
dockerfile: zotero/Dockerfile
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build zotero
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: zotero/
|
||||
file: zotero/Dockerfile
|
||||
push: false
|
||||
tags: ci-test-zotero
|
||||
load: true
|
||||
|
||||
docs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Hadolint docs
|
||||
uses: hadolint/hadolint-action@v3.1.0
|
||||
with:
|
||||
dockerfile: docs/Dockerfile
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build docs
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: docs/Dockerfile
|
||||
push: false
|
||||
tags: ci-test-docs
|
||||
load: true
|
||||
|
||||
api:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Hadolint api
|
||||
uses: hadolint/hadolint-action@v3.1.0
|
||||
with:
|
||||
dockerfile: api/Dockerfile
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build api
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: api/Dockerfile
|
||||
push: false
|
||||
tags: ci-test-api
|
||||
load: true
|
||||
|
||||
mc:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Hadolint mc
|
||||
uses: hadolint/hadolint-action@v3.1.0
|
||||
with:
|
||||
dockerfile: rustfs/Dockerfile.mc
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build mc
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: rustfs/
|
||||
file: rustfs/Dockerfile.mc
|
||||
push: false
|
||||
tags: ci-test-mc
|
||||
load: true
|
||||
145
.gitea/workflows/rebuild-all.yml
Normal file
145
.gitea/workflows/rebuild-all.yml
Normal file
@@ -0,0 +1,145 @@
|
||||
# DO NOT EDIT — generated by gen_config.py from stack.toml
|
||||
# Re-generate: uv run python dev/scripts/gen_config.py
|
||||
|
||||
name: Rebuild All
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to container registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: gitea.homelab.fhirworx.io
|
||||
username: ${{ secrets.REGISTRY_USER }}
|
||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||
|
||||
- name: Compute short SHA
|
||||
run: echo "SHORT_SHA=${{GITHUB_SHA::8}}" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build notebooks
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: notebooks/
|
||||
file: notebooks/Dockerfile
|
||||
push: true
|
||||
tags: gitea.homelab.fhirworx.io/homelab/stack/notebooks:${{ env.SHORT_SHA }},gitea.homelab.fhirworx.io/homelab/stack/notebooks:latest
|
||||
|
||||
- name: Build zotero
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: zotero/
|
||||
file: zotero/Dockerfile
|
||||
push: true
|
||||
tags: gitea.homelab.fhirworx.io/homelab/stack/zotero:${{ env.SHORT_SHA }},gitea.homelab.fhirworx.io/homelab/stack/zotero:latest
|
||||
|
||||
- name: Build docs
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: docs/Dockerfile
|
||||
push: true
|
||||
tags: gitea.homelab.fhirworx.io/homelab/stack/docs:${{ env.SHORT_SHA }},gitea.homelab.fhirworx.io/homelab/stack/docs:latest
|
||||
|
||||
- name: Build api
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: api/Dockerfile
|
||||
push: true
|
||||
tags: gitea.homelab.fhirworx.io/homelab/stack/api:${{ env.SHORT_SHA }},gitea.homelab.fhirworx.io/homelab/stack/api:latest
|
||||
|
||||
- name: Build mc
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: rustfs/
|
||||
file: rustfs/Dockerfile.mc
|
||||
push: true
|
||||
tags: gitea.homelab.fhirworx.io/homelab/stack/mc:${{ env.SHORT_SHA }},gitea.homelab.fhirworx.io/homelab/stack/mc:latest
|
||||
|
||||
scan:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Compute short SHA
|
||||
run: echo "SHORT_SHA=${{GITHUB_SHA::8}}" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Scan notebooks
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: gitea.homelab.fhirworx.io/homelab/stack/notebooks:${{ env.SHORT_SHA }}
|
||||
severity: HIGH,CRITICAL
|
||||
exit-code: "0"
|
||||
format: json
|
||||
output: notebooks-scan.json
|
||||
|
||||
- name: Scan zotero
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: gitea.homelab.fhirworx.io/homelab/stack/zotero:${{ env.SHORT_SHA }}
|
||||
severity: HIGH,CRITICAL
|
||||
exit-code: "0"
|
||||
format: json
|
||||
output: zotero-scan.json
|
||||
|
||||
- name: Scan docs
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: gitea.homelab.fhirworx.io/homelab/stack/docs:${{ env.SHORT_SHA }}
|
||||
severity: HIGH,CRITICAL
|
||||
exit-code: "0"
|
||||
format: json
|
||||
output: docs-scan.json
|
||||
|
||||
- name: Scan api
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: gitea.homelab.fhirworx.io/homelab/stack/api:${{ env.SHORT_SHA }}
|
||||
severity: HIGH,CRITICAL
|
||||
exit-code: "0"
|
||||
format: json
|
||||
output: api-scan.json
|
||||
|
||||
- name: Upload scan results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: trivy-scans-rebuild
|
||||
path: "*-scan.json"
|
||||
|
||||
report-vulns:
|
||||
runs-on: ubuntu-latest
|
||||
needs: scan
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up uv
|
||||
uses: astral-sh/setup-uv@v4
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Download scan results
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: trivy-scans-rebuild
|
||||
|
||||
- name: Report vulnerabilities
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
run: |
|
||||
uv sync --no-dev
|
||||
for f in notebooks-scan.json zotero-scan.json docs-scan.json api-scan.json; do
|
||||
[ -f "$f" ] && uv run python -m api.diag.vuln "$f" || true
|
||||
done
|
||||
30
.gitea/workflows/release.yml
Normal file
30
.gitea/workflows/release.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
# DO NOT EDIT — generated by gen_config.py from stack.toml
|
||||
# Re-generate: uv run python dev/scripts/gen_config.py
|
||||
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: ["v*"]
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up uv
|
||||
uses: astral-sh/setup-uv@v4
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Build package
|
||||
run: uv build --out-dir dist/
|
||||
|
||||
- name: Create release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
dist/*.whl
|
||||
dist/*.tar.gz
|
||||
@@ -1,128 +0,0 @@
|
||||
# ── Quality gate (generated by gen_config.py — woodpecker backend) ──
|
||||
# DO NOT EDIT — edit stack.toml and run gen_config.py
|
||||
|
||||
when:
|
||||
- event: [push, pull_request, manual]
|
||||
|
||||
steps:
|
||||
- name: lint
|
||||
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||
environment:
|
||||
UV_PYTHON_PREFERENCE: only-system
|
||||
UV_LINK_MODE: copy
|
||||
UV_PROJECT_ENVIRONMENT: .venv
|
||||
commands:
|
||||
- uv sync --dev
|
||||
- uv run ruff check src/ tests/ --output-format=concise
|
||||
- uv run ruff format --check src/ tests/
|
||||
|
||||
- name: test
|
||||
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||
environment:
|
||||
UV_PYTHON_PREFERENCE: only-system
|
||||
UV_LINK_MODE: copy
|
||||
UV_PROJECT_ENVIRONMENT: .venv
|
||||
commands:
|
||||
- uv run pytest tests/ --cov=src --cov-report=term-missing --cov-fail-under=99 -q 2>&1 | tee pytest.out
|
||||
- uv run python dev/scripts/coverage_badge.py < pytest.out > coverage.svg
|
||||
depends_on:
|
||||
- lint
|
||||
|
||||
- name: coverage-badge
|
||||
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||
failure: ignore
|
||||
environment:
|
||||
UV_PYTHON_PREFERENCE: only-system
|
||||
UV_LINK_MODE: copy
|
||||
UV_PROJECT_ENVIRONMENT: .venv
|
||||
GITEA_TOKEN:
|
||||
from_secret: gitea_token
|
||||
GITEA_URL:
|
||||
from_secret: gitea_url
|
||||
commands:
|
||||
- uv run python dev/scripts/coverage_badge.py --post pytest.out
|
||||
depends_on:
|
||||
- test
|
||||
|
||||
- name: commit-badge
|
||||
image: alpine/git
|
||||
failure: ignore
|
||||
environment:
|
||||
REGISTRY_USER:
|
||||
from_secret: registry_user
|
||||
REGISTRY_PASS:
|
||||
from_secret: registry_pass
|
||||
commands:
|
||||
- git config user.name woodpecker-ci
|
||||
- git config user.email ci@${CI_REPO_OWNER}.io
|
||||
- git add coverage.svg
|
||||
- git diff --cached --quiet && echo "no change" && exit 0
|
||||
- git commit -m "update coverage badge [skip ci]"
|
||||
- git push http://$REGISTRY_USER:$REGISTRY_PASS@gitea:3000/${CI_REPO}.git HEAD:main
|
||||
when:
|
||||
- branch: main
|
||||
event: push
|
||||
depends_on:
|
||||
- test
|
||||
|
||||
- name: upload-coverage-badge
|
||||
image: woodpeckerci/plugin-s3
|
||||
failure: ignore
|
||||
settings:
|
||||
endpoint: http://rustfs:9000
|
||||
bucket: gitea
|
||||
access_key:
|
||||
from_secret: s3_access_key
|
||||
secret_key:
|
||||
from_secret: s3_secret_key
|
||||
source: "coverage.svg"
|
||||
target: /badges/${CI_REPO}/
|
||||
path_style: true
|
||||
overwrite: true
|
||||
depends_on:
|
||||
- test
|
||||
|
||||
- name: pr-comment
|
||||
image: woodpeckerci/plugin-gitea-comment
|
||||
settings:
|
||||
gitea_url:
|
||||
from_secret: gitea_url
|
||||
api_key:
|
||||
from_secret: gitea_token
|
||||
message: >
|
||||
**CI** for `${CI_COMMIT_SHA:0:8}` —
|
||||
[pipeline #${CI_PIPELINE_NUMBER}](${CI_PIPELINE_URL})
|
||||
when:
|
||||
- event: pull_request
|
||||
depends_on:
|
||||
- test
|
||||
- coverage-badge
|
||||
|
||||
- name: validate-compose
|
||||
image: docker:cli
|
||||
volumes:
|
||||
- /run/user/1000/docker.sock:/var/run/docker.sock
|
||||
commands:
|
||||
- docker compose config --quiet
|
||||
|
||||
- name: validate-gen-config
|
||||
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||
environment:
|
||||
UV_PYTHON_PREFERENCE: only-system
|
||||
UV_LINK_MODE: copy
|
||||
UV_PROJECT_ENVIRONMENT: .venv
|
||||
commands:
|
||||
- uv run python dev/scripts/gen_config.py --check
|
||||
|
||||
# ── Failure reporter ─────────────────────────────────────────
|
||||
- name: report-failure
|
||||
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||
failure: ignore
|
||||
environment:
|
||||
<<: *diag_env
|
||||
commands:
|
||||
- uv sync --no-dev
|
||||
- uv run python -m api.diag
|
||||
when:
|
||||
- status: [failure]
|
||||
|
||||
@@ -1,261 +0,0 @@
|
||||
# ── Deploy pipeline (generated by gen_config.py — woodpecker backend) ──
|
||||
# DO NOT EDIT — edit stack.toml [images] and run gen_config.py
|
||||
|
||||
when:
|
||||
- event: push
|
||||
branch: main
|
||||
|
||||
variables:
|
||||
- &buildx_image woodpeckerci/plugin-docker-buildx:5-insecure
|
||||
- ®istry gitea.homelab.fhirworx.io
|
||||
- &org homelab
|
||||
- &image_prefix fhirworx
|
||||
- &buildx_base
|
||||
buildkit_config: |
|
||||
[registry."gitea.homelab.fhirworx.io"]
|
||||
http = true
|
||||
registry: *registry
|
||||
username:
|
||||
from_secret: registry_user
|
||||
password:
|
||||
from_secret: registry_pass
|
||||
- &trivy_scan
|
||||
image: aquasec/trivy:latest
|
||||
environment:
|
||||
REGISTRY: *registry
|
||||
ORG: *org
|
||||
- &diag_env
|
||||
UV_PYTHON_PREFERENCE: only-system
|
||||
UV_LINK_MODE: copy
|
||||
UV_PROJECT_ENVIRONMENT: .venv
|
||||
GITEA_TOKEN:
|
||||
from_secret: gitea_token
|
||||
|
||||
steps:
|
||||
# ── Python package ──────────────────────────────────────────
|
||||
- name: build-package
|
||||
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||
commands:
|
||||
- BASE=$(grep '^version' pyproject.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
|
||||
- uv version "$BASE.dev${CI_PIPELINE_NUMBER}" --no-sync
|
||||
- uv build --out-dir dist/
|
||||
- ls -lh dist/
|
||||
|
||||
- name: publish-package
|
||||
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||
environment:
|
||||
REGISTRY_USER:
|
||||
from_secret: registry_user
|
||||
REGISTRY_PASS:
|
||||
from_secret: registry_pass
|
||||
commands:
|
||||
- uv publish --publish-url http://gitea:3000/api/packages/${CI_REPO_OWNER}/pypi --username "$REGISTRY_USER" --password "$REGISTRY_PASS" dist/*
|
||||
depends_on:
|
||||
- build-package
|
||||
|
||||
# ── Container images ──────────────────────────────────────
|
||||
- name: build-push-notebooks
|
||||
image: *buildx_image
|
||||
settings:
|
||||
<<: *buildx_base
|
||||
repo: gitea.homelab.fhirworx.io/homelab/notebooks
|
||||
dockerfile: notebooks/Dockerfile
|
||||
context: notebooks/
|
||||
tags:
|
||||
- "${CI_COMMIT_SHA:0:8}"
|
||||
- "latest"
|
||||
|
||||
- name: build-push-zotero
|
||||
image: *buildx_image
|
||||
settings:
|
||||
<<: *buildx_base
|
||||
repo: gitea.homelab.fhirworx.io/homelab/zotero
|
||||
dockerfile: zotero/Dockerfile
|
||||
context: zotero/
|
||||
tags:
|
||||
- "${CI_COMMIT_SHA:0:8}"
|
||||
- "latest"
|
||||
|
||||
- name: prep-docs-context
|
||||
image: alpine:3
|
||||
volumes:
|
||||
- ${CI_WORKSPACE}/data:/host-data:ro
|
||||
commands:
|
||||
- mkdir -p data
|
||||
- cp /host-data/bib.sqlite data/ 2>/dev/null || true
|
||||
|
||||
- name: build-push-docs
|
||||
image: *buildx_image
|
||||
settings:
|
||||
<<: *buildx_base
|
||||
repo: gitea.homelab.fhirworx.io/homelab/docs
|
||||
dockerfile: docs/Dockerfile
|
||||
context: .
|
||||
tags:
|
||||
- "${CI_COMMIT_SHA:0:8}"
|
||||
- "latest"
|
||||
depends_on:
|
||||
- prep-docs-context
|
||||
|
||||
- name: build-push-api
|
||||
image: *buildx_image
|
||||
settings:
|
||||
<<: *buildx_base
|
||||
repo: gitea.homelab.fhirworx.io/homelab/api
|
||||
dockerfile: api/Dockerfile
|
||||
context: .
|
||||
tags:
|
||||
- "${CI_COMMIT_SHA:0:8}"
|
||||
- "latest"
|
||||
|
||||
- name: build-push-mc
|
||||
image: *buildx_image
|
||||
settings:
|
||||
<<: *buildx_base
|
||||
repo: gitea.homelab.fhirworx.io/homelab/mc
|
||||
dockerfile: rustfs/Dockerfile.mc
|
||||
context: rustfs/
|
||||
tags:
|
||||
- "${CI_COMMIT_SHA:0:8}"
|
||||
- "latest"
|
||||
|
||||
# ── Scan images ──────────────────────────────────────────
|
||||
- name: scan-notebooks
|
||||
<<: *trivy_scan
|
||||
commands:
|
||||
- trivy image --image-src remote --insecure --severity HIGH,CRITICAL
|
||||
--exit-code 0 --format json -o notebooks-scan.json
|
||||
"$REGISTRY/$ORG/notebooks:${CI_COMMIT_SHA:0:8}"
|
||||
depends_on: [build-push-notebooks]
|
||||
|
||||
- name: scan-zotero
|
||||
<<: *trivy_scan
|
||||
commands:
|
||||
- trivy image --image-src remote --insecure --severity HIGH,CRITICAL
|
||||
--exit-code 0 --format json -o zotero-scan.json
|
||||
"$REGISTRY/$ORG/zotero:${CI_COMMIT_SHA:0:8}"
|
||||
depends_on: [build-push-zotero]
|
||||
|
||||
- name: scan-docs
|
||||
<<: *trivy_scan
|
||||
commands:
|
||||
- trivy image --image-src remote --insecure --severity HIGH,CRITICAL
|
||||
--exit-code 0 --format json -o docs-scan.json
|
||||
"$REGISTRY/$ORG/docs:${CI_COMMIT_SHA:0:8}"
|
||||
depends_on: [build-push-docs]
|
||||
|
||||
- name: scan-api
|
||||
<<: *trivy_scan
|
||||
commands:
|
||||
- trivy image --image-src remote --insecure --severity HIGH,CRITICAL
|
||||
--exit-code 0 --format json -o api-scan.json
|
||||
"$REGISTRY/$ORG/api:${CI_COMMIT_SHA:0:8}"
|
||||
depends_on: [build-push-api]
|
||||
|
||||
# ── Upload scan results ─────────────────────────────────
|
||||
- name: upload-notebooks-scan
|
||||
image: woodpeckerci/plugin-s3
|
||||
failure: ignore
|
||||
settings:
|
||||
endpoint: http://rustfs:9000
|
||||
bucket: gitea
|
||||
access_key:
|
||||
from_secret: s3_access_key
|
||||
secret_key:
|
||||
from_secret: s3_secret_key
|
||||
source: "notebooks-scan.json"
|
||||
target: /ci/${CI_REPO}/${CI_COMMIT_SHA:0:8}/
|
||||
path_style: true
|
||||
depends_on:
|
||||
- scan-notebooks
|
||||
|
||||
- name: upload-zotero-scan
|
||||
image: woodpeckerci/plugin-s3
|
||||
failure: ignore
|
||||
settings:
|
||||
endpoint: http://rustfs:9000
|
||||
bucket: gitea
|
||||
access_key:
|
||||
from_secret: s3_access_key
|
||||
secret_key:
|
||||
from_secret: s3_secret_key
|
||||
source: "zotero-scan.json"
|
||||
target: /ci/${CI_REPO}/${CI_COMMIT_SHA:0:8}/
|
||||
path_style: true
|
||||
depends_on:
|
||||
- scan-zotero
|
||||
|
||||
- name: upload-docs-scan
|
||||
image: woodpeckerci/plugin-s3
|
||||
failure: ignore
|
||||
settings:
|
||||
endpoint: http://rustfs:9000
|
||||
bucket: gitea
|
||||
access_key:
|
||||
from_secret: s3_access_key
|
||||
secret_key:
|
||||
from_secret: s3_secret_key
|
||||
source: "docs-scan.json"
|
||||
target: /ci/${CI_REPO}/${CI_COMMIT_SHA:0:8}/
|
||||
path_style: true
|
||||
depends_on:
|
||||
- scan-docs
|
||||
|
||||
- name: upload-api-scan
|
||||
image: woodpeckerci/plugin-s3
|
||||
failure: ignore
|
||||
settings:
|
||||
endpoint: http://rustfs:9000
|
||||
bucket: gitea
|
||||
access_key:
|
||||
from_secret: s3_access_key
|
||||
secret_key:
|
||||
from_secret: s3_secret_key
|
||||
source: "api-scan.json"
|
||||
target: /ci/${CI_REPO}/${CI_COMMIT_SHA:0:8}/
|
||||
path_style: true
|
||||
depends_on:
|
||||
- scan-api
|
||||
|
||||
# ── Report vulnerabilities ──────────────────────────────
|
||||
- name: report-vulns
|
||||
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||
failure: ignore
|
||||
environment:
|
||||
<<: *diag_env
|
||||
commands:
|
||||
- uv sync --no-dev
|
||||
- |
|
||||
for f in notebooks-scan.json zotero-scan.json docs-scan.json api-scan.json; do
|
||||
[ -f "$f" ] && uv run python -m api.diag.vuln "$f" || true
|
||||
done
|
||||
depends_on:
|
||||
- scan-notebooks
|
||||
- scan-zotero
|
||||
- scan-docs
|
||||
- scan-api
|
||||
|
||||
# ── Deploy (disabled — manual only) ────────────────────
|
||||
- name: deploy
|
||||
image: alpine:3
|
||||
commands:
|
||||
- echo "Deploy disabled — run manually after green pipeline"
|
||||
depends_on:
|
||||
- publish-package
|
||||
- scan-notebooks
|
||||
- scan-zotero
|
||||
- scan-docs
|
||||
- scan-api
|
||||
- build-push-mc
|
||||
|
||||
# ── Failure reporter ─────────────────────────────────────────
|
||||
- name: report-failure
|
||||
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||
failure: ignore
|
||||
environment:
|
||||
<<: *diag_env
|
||||
commands:
|
||||
- uv sync --no-dev
|
||||
- uv run python -m api.diag
|
||||
when:
|
||||
- status: [failure]
|
||||
@@ -1,158 +0,0 @@
|
||||
# ── Hardening pipeline (generated by gen_config.py — woodpecker backend) ──
|
||||
# DO NOT EDIT — edit stack.toml [images] and run gen_config.py
|
||||
|
||||
when:
|
||||
- event: [manual, cron]
|
||||
|
||||
variables:
|
||||
- &buildx_image woodpeckerci/plugin-docker-buildx:5-insecure
|
||||
- ®istry gitea.homelab.fhirworx.io
|
||||
- &org homelab
|
||||
- &image_prefix fhirworx
|
||||
- &buildx_base
|
||||
buildkit_config: |
|
||||
[registry."gitea.homelab.fhirworx.io"]
|
||||
http = true
|
||||
registry: *registry
|
||||
username:
|
||||
from_secret: registry_user
|
||||
password:
|
||||
from_secret: registry_pass
|
||||
- &trivy_scan
|
||||
image: aquasec/trivy:latest
|
||||
environment:
|
||||
REGISTRY: *registry
|
||||
ORG: *org
|
||||
- &diag_env
|
||||
UV_PYTHON_PREFERENCE: only-system
|
||||
UV_LINK_MODE: copy
|
||||
UV_PROJECT_ENVIRONMENT: .venv
|
||||
GITEA_TOKEN:
|
||||
from_secret: gitea_token
|
||||
|
||||
steps:
|
||||
# ── Build hardened images ──────────────────────────────────
|
||||
- name: build-notebooks
|
||||
image: *buildx_image
|
||||
settings:
|
||||
<<: *buildx_base
|
||||
repo: gitea.homelab.fhirworx.io/homelab/notebooks
|
||||
dockerfile: notebooks/Dockerfile
|
||||
context: notebooks/
|
||||
tags:
|
||||
- "hardened"
|
||||
- "latest"
|
||||
no_cache: true
|
||||
|
||||
- name: build-zotero
|
||||
image: *buildx_image
|
||||
settings:
|
||||
<<: *buildx_base
|
||||
repo: gitea.homelab.fhirworx.io/homelab/zotero
|
||||
dockerfile: zotero/Dockerfile
|
||||
context: zotero/
|
||||
tags:
|
||||
- "hardened"
|
||||
- "latest"
|
||||
no_cache: true
|
||||
|
||||
- name: build-docs
|
||||
image: *buildx_image
|
||||
settings:
|
||||
<<: *buildx_base
|
||||
repo: gitea.homelab.fhirworx.io/homelab/docs
|
||||
dockerfile: docs/Dockerfile
|
||||
context: .
|
||||
tags:
|
||||
- "hardened"
|
||||
- "latest"
|
||||
no_cache: true
|
||||
|
||||
- name: build-api
|
||||
image: *buildx_image
|
||||
settings:
|
||||
<<: *buildx_base
|
||||
repo: gitea.homelab.fhirworx.io/homelab/api
|
||||
dockerfile: api/Dockerfile
|
||||
context: .
|
||||
tags:
|
||||
- "hardened"
|
||||
- "latest"
|
||||
no_cache: true
|
||||
|
||||
- name: build-mc
|
||||
image: *buildx_image
|
||||
settings:
|
||||
<<: *buildx_base
|
||||
repo: gitea.homelab.fhirworx.io/homelab/mc
|
||||
dockerfile: rustfs/Dockerfile.mc
|
||||
context: rustfs/
|
||||
tags:
|
||||
- "hardened"
|
||||
- "latest"
|
||||
no_cache: true
|
||||
|
||||
# ── Scan hardened images ───────────────────────────────────
|
||||
- name: scan-notebooks
|
||||
<<: *trivy_scan
|
||||
commands:
|
||||
- trivy image --image-src remote --insecure --severity HIGH,CRITICAL
|
||||
--exit-code 0 --format json -o notebooks-scan.json
|
||||
"$REGISTRY/$ORG/notebooks:hardened"
|
||||
depends_on: [build-push-notebooks]
|
||||
|
||||
- name: scan-zotero
|
||||
<<: *trivy_scan
|
||||
commands:
|
||||
- trivy image --image-src remote --insecure --severity HIGH,CRITICAL
|
||||
--exit-code 0 --format json -o zotero-scan.json
|
||||
"$REGISTRY/$ORG/zotero:hardened"
|
||||
depends_on: [build-push-zotero]
|
||||
|
||||
- name: scan-docs
|
||||
<<: *trivy_scan
|
||||
commands:
|
||||
- trivy image --image-src remote --insecure --severity HIGH,CRITICAL
|
||||
--exit-code 0 --format json -o docs-scan.json
|
||||
"$REGISTRY/$ORG/docs:hardened"
|
||||
depends_on: [build-push-docs]
|
||||
|
||||
- name: scan-api
|
||||
<<: *trivy_scan
|
||||
commands:
|
||||
- trivy image --image-src remote --insecure --severity HIGH,CRITICAL
|
||||
--exit-code 0 --format json -o api-scan.json
|
||||
"$REGISTRY/$ORG/api:hardened"
|
||||
depends_on: [build-push-api]
|
||||
|
||||
# ── Close resolved vuln issues OR file new ones ────────────
|
||||
- name: close-or-report-vulns
|
||||
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||
environment:
|
||||
<<: *diag_env
|
||||
commands:
|
||||
- uv sync --no-dev
|
||||
- |
|
||||
for f in notebooks-scan.json zotero-scan.json docs-scan.json api-scan.json; do
|
||||
if [ -f "$f" ]; then
|
||||
uv run python -m api.diag.vuln --close "$f" || \
|
||||
uv run python -m api.diag.vuln "$f" || true
|
||||
fi
|
||||
done
|
||||
depends_on:
|
||||
- scan-notebooks
|
||||
- scan-zotero
|
||||
- scan-docs
|
||||
- scan-api
|
||||
|
||||
# ── Failure reporter ─────────────────────────────────────────
|
||||
- name: report-failure
|
||||
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||
failure: ignore
|
||||
environment:
|
||||
<<: *diag_env
|
||||
commands:
|
||||
- uv sync --no-dev
|
||||
- uv run python -m api.diag
|
||||
when:
|
||||
- status: [failure]
|
||||
@@ -1,203 +0,0 @@
|
||||
# ── Infrastructure quality gate (generated by gen_config.py — woodpecker backend) ──
|
||||
# DO NOT EDIT — edit stack.toml [images] and run gen_config.py
|
||||
|
||||
when:
|
||||
- event: [push, pull_request, manual]
|
||||
|
||||
steps:
|
||||
- name: infra-gate
|
||||
image: alpine:3
|
||||
commands:
|
||||
- echo "infra-ci gate passed"
|
||||
|
||||
- name: hadolint-notebooks
|
||||
image: hadolint/hadolint:latest-debian
|
||||
commands:
|
||||
- hadolint notebooks/Dockerfile
|
||||
when:
|
||||
- path: "notebooks/**"
|
||||
|
||||
- name: build-notebooks
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
dockerfile: notebooks/Dockerfile
|
||||
context: notebooks/
|
||||
tags: ["ci-test"]
|
||||
daemon_off: true
|
||||
dry_run: true
|
||||
volumes:
|
||||
- /run/user/1000/docker.sock:/var/run/docker.sock
|
||||
depends_on:
|
||||
- hadolint-notebooks
|
||||
when:
|
||||
- path: "notebooks/**"
|
||||
|
||||
- name: hadolint-zotero
|
||||
image: hadolint/hadolint:latest-debian
|
||||
commands:
|
||||
- hadolint zotero/Dockerfile
|
||||
when:
|
||||
- path: "zotero/**"
|
||||
|
||||
- name: build-zotero
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
dockerfile: zotero/Dockerfile
|
||||
context: zotero/
|
||||
tags: ["ci-test"]
|
||||
daemon_off: true
|
||||
dry_run: true
|
||||
volumes:
|
||||
- /run/user/1000/docker.sock:/var/run/docker.sock
|
||||
depends_on:
|
||||
- hadolint-zotero
|
||||
when:
|
||||
- path: "zotero/**"
|
||||
|
||||
- name: hadolint-docs
|
||||
image: hadolint/hadolint:latest-debian
|
||||
commands:
|
||||
- hadolint docs/Dockerfile
|
||||
when:
|
||||
- path: "docs/**"
|
||||
|
||||
- name: build-docs
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
dockerfile: docs/Dockerfile
|
||||
context: .
|
||||
tags: ["ci-test"]
|
||||
daemon_off: true
|
||||
dry_run: true
|
||||
volumes:
|
||||
- /run/user/1000/docker.sock:/var/run/docker.sock
|
||||
depends_on:
|
||||
- hadolint-docs
|
||||
when:
|
||||
- path: "docs/**"
|
||||
|
||||
- name: hadolint-api
|
||||
image: hadolint/hadolint:latest-debian
|
||||
commands:
|
||||
- hadolint api/Dockerfile
|
||||
when:
|
||||
- path:
|
||||
- "api/**"
|
||||
- "src/**"
|
||||
- "pyproject.toml"
|
||||
|
||||
- name: build-api
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
dockerfile: api/Dockerfile
|
||||
context: .
|
||||
tags: ["ci-test"]
|
||||
daemon_off: true
|
||||
dry_run: true
|
||||
volumes:
|
||||
- /run/user/1000/docker.sock:/var/run/docker.sock
|
||||
depends_on:
|
||||
- hadolint-api
|
||||
when:
|
||||
- path:
|
||||
- "api/**"
|
||||
- "src/**"
|
||||
- "pyproject.toml"
|
||||
|
||||
- name: hadolint-mc
|
||||
image: hadolint/hadolint:latest-debian
|
||||
commands:
|
||||
- hadolint rustfs/Dockerfile.mc
|
||||
when:
|
||||
- path: "rustfs/**"
|
||||
|
||||
- name: build-mc
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
dockerfile: rustfs/Dockerfile.mc
|
||||
context: rustfs/
|
||||
tags: ["ci-test"]
|
||||
daemon_off: true
|
||||
dry_run: true
|
||||
volumes:
|
||||
- /run/user/1000/docker.sock:/var/run/docker.sock
|
||||
depends_on:
|
||||
- hadolint-mc
|
||||
when:
|
||||
- path: "rustfs/**"
|
||||
|
||||
# ── Config validation ────────────────────────────────────
|
||||
- name: validate-nginx
|
||||
image: nginx:alpine
|
||||
commands:
|
||||
- cp nginx/nginx.conf /etc/nginx/nginx.conf
|
||||
- nginx -t
|
||||
when:
|
||||
- path: "nginx/**"
|
||||
|
||||
- name: validate-prometheus
|
||||
image: prom/prometheus:latest
|
||||
commands:
|
||||
- promtool check config prometheus/prometheus.yml
|
||||
when:
|
||||
- path: "prometheus/**"
|
||||
|
||||
- name: validate-traefik-static
|
||||
image: cytopia/yamllint:latest
|
||||
commands:
|
||||
- yamllint -d relaxed traefik/traefik.yml
|
||||
when:
|
||||
- path: "traefik/traefik.yml"
|
||||
|
||||
- name: validate-traefik-template
|
||||
image: traefik:v3.3
|
||||
environment:
|
||||
DOMAIN: ci-test.example.com
|
||||
commands:
|
||||
- |
|
||||
timeout 5 traefik \
|
||||
--providers.file.directory=traefik/dynamic \
|
||||
--api.dashboard=false \
|
||||
--log.level=DEBUG 2>&1 | head -80 || true
|
||||
- echo "Traefik template syntax OK"
|
||||
when:
|
||||
- path: "traefik/dynamic/**"
|
||||
|
||||
- name: validate-loki
|
||||
image: cytopia/yamllint:latest
|
||||
commands:
|
||||
- yamllint -d relaxed loki/
|
||||
when:
|
||||
- path: "loki/**"
|
||||
|
||||
- name: validate-trino
|
||||
image: alpine:3
|
||||
commands:
|
||||
- |
|
||||
OK=true
|
||||
for f in trino/etc/config.properties trino/etc/node.properties trino/etc/jvm.config; do
|
||||
if [ ! -f "$f" ]; then echo "MISSING: $f"; OK=false; fi
|
||||
done
|
||||
ls trino/etc/catalog/*.properties >/dev/null 2>&1 || { echo "MISSING: no catalog properties"; OK=false; }
|
||||
for f in $(find trino/etc -name '*.properties'); do
|
||||
while IFS= read -r line; do
|
||||
case "$line" in ''|'#'*|'!'*) continue ;; esac
|
||||
echo "$line" | grep -q '=' || { echo "BAD LINE in $f: $line"; OK=false; }
|
||||
done < "$f"
|
||||
done
|
||||
$OK && echo "Trino config validation passed"
|
||||
$OK
|
||||
when:
|
||||
- path: "trino/etc/**"
|
||||
|
||||
# ── Failure reporter ─────────────────────────────────────────
|
||||
- name: report-failure
|
||||
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||
failure: ignore
|
||||
environment:
|
||||
<<: *diag_env
|
||||
commands:
|
||||
- uv sync --no-dev
|
||||
- uv run python -m api.diag
|
||||
when:
|
||||
- status: [failure]
|
||||
@@ -1,191 +0,0 @@
|
||||
# ── Rebuild-all pipeline (generated by gen_config.py — woodpecker backend) ──
|
||||
# DO NOT EDIT — edit stack.toml [images] and run gen_config.py
|
||||
|
||||
when:
|
||||
- event: manual
|
||||
|
||||
variables:
|
||||
- &buildx_image woodpeckerci/plugin-docker-buildx:5-insecure
|
||||
- ®istry gitea.homelab.fhirworx.io
|
||||
- &org homelab
|
||||
- &image_prefix fhirworx
|
||||
- &buildx_base
|
||||
buildkit_config: |
|
||||
[registry."gitea.homelab.fhirworx.io"]
|
||||
http = true
|
||||
registry: *registry
|
||||
username:
|
||||
from_secret: registry_user
|
||||
password:
|
||||
from_secret: registry_pass
|
||||
- &trivy_scan
|
||||
image: aquasec/trivy:latest
|
||||
environment:
|
||||
REGISTRY: *registry
|
||||
ORG: *org
|
||||
- &diag_env
|
||||
UV_PYTHON_PREFERENCE: only-system
|
||||
UV_LINK_MODE: copy
|
||||
UV_PROJECT_ENVIRONMENT: .venv
|
||||
GITEA_TOKEN:
|
||||
from_secret: gitea_token
|
||||
|
||||
steps:
|
||||
- name: build-push-notebooks
|
||||
image: *buildx_image
|
||||
settings:
|
||||
<<: *buildx_base
|
||||
repo: gitea.homelab.fhirworx.io/homelab/notebooks
|
||||
dockerfile: notebooks/Dockerfile
|
||||
context: notebooks/
|
||||
tags:
|
||||
- "${CI_COMMIT_SHA:0:8}"
|
||||
- "latest"
|
||||
|
||||
- name: build-push-zotero
|
||||
image: *buildx_image
|
||||
settings:
|
||||
<<: *buildx_base
|
||||
repo: gitea.homelab.fhirworx.io/homelab/zotero
|
||||
dockerfile: zotero/Dockerfile
|
||||
context: zotero/
|
||||
tags:
|
||||
- "${CI_COMMIT_SHA:0:8}"
|
||||
- "latest"
|
||||
|
||||
- name: prep-docs-context
|
||||
image: alpine:3
|
||||
environment:
|
||||
STACK_ROOT:
|
||||
from_secret: stack_root
|
||||
volumes:
|
||||
- ${CI_WORKSPACE}/data:/host-data:ro
|
||||
commands:
|
||||
- mkdir -p data
|
||||
- cp /host-data/bib.sqlite data/ 2>/dev/null || true
|
||||
|
||||
- name: build-push-docs
|
||||
image: *buildx_image
|
||||
settings:
|
||||
<<: *buildx_base
|
||||
repo: gitea.homelab.fhirworx.io/homelab/docs
|
||||
dockerfile: docs/Dockerfile
|
||||
context: .
|
||||
tags:
|
||||
- "${CI_COMMIT_SHA:0:8}"
|
||||
- "latest"
|
||||
depends_on:
|
||||
- prep-docs-context
|
||||
|
||||
- name: build-push-api
|
||||
image: *buildx_image
|
||||
settings:
|
||||
<<: *buildx_base
|
||||
repo: gitea.homelab.fhirworx.io/homelab/api
|
||||
dockerfile: api/Dockerfile
|
||||
context: .
|
||||
tags:
|
||||
- "${CI_COMMIT_SHA:0:8}"
|
||||
- "latest"
|
||||
|
||||
- name: build-push-mc
|
||||
image: *buildx_image
|
||||
settings:
|
||||
<<: *buildx_base
|
||||
repo: gitea.homelab.fhirworx.io/homelab/mc
|
||||
dockerfile: rustfs/Dockerfile.mc
|
||||
context: rustfs/
|
||||
tags:
|
||||
- "${CI_COMMIT_SHA:0:8}"
|
||||
- "latest"
|
||||
|
||||
# ── Scan images ──────────────────────────────────────────
|
||||
- name: scan-notebooks
|
||||
<<: *trivy_scan
|
||||
commands:
|
||||
- trivy image --image-src remote --insecure --severity HIGH,CRITICAL
|
||||
--exit-code 0 --format json -o notebooks-scan.json
|
||||
"$REGISTRY/$ORG/notebooks:${CI_COMMIT_SHA:0:8}"
|
||||
depends_on: [build-push-notebooks]
|
||||
|
||||
- name: scan-zotero
|
||||
<<: *trivy_scan
|
||||
commands:
|
||||
- trivy image --image-src remote --insecure --severity HIGH,CRITICAL
|
||||
--exit-code 0 --format json -o zotero-scan.json
|
||||
"$REGISTRY/$ORG/zotero:${CI_COMMIT_SHA:0:8}"
|
||||
depends_on: [build-push-zotero]
|
||||
|
||||
- name: scan-docs
|
||||
<<: *trivy_scan
|
||||
commands:
|
||||
- trivy image --image-src remote --insecure --severity HIGH,CRITICAL
|
||||
--exit-code 0 --format json -o docs-scan.json
|
||||
"$REGISTRY/$ORG/docs:${CI_COMMIT_SHA:0:8}"
|
||||
depends_on: [build-push-docs]
|
||||
|
||||
- name: scan-api
|
||||
<<: *trivy_scan
|
||||
commands:
|
||||
- trivy image --image-src remote --insecure --severity HIGH,CRITICAL
|
||||
--exit-code 0 --format json -o api-scan.json
|
||||
"$REGISTRY/$ORG/api:${CI_COMMIT_SHA:0:8}"
|
||||
depends_on: [build-push-api]
|
||||
|
||||
# ── Report vulnerabilities ──────────────────────────────
|
||||
- name: report-vulns
|
||||
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||
failure: ignore
|
||||
environment:
|
||||
<<: *diag_env
|
||||
commands:
|
||||
- uv sync --no-dev
|
||||
- |
|
||||
for f in notebooks-scan.json zotero-scan.json docs-scan.json api-scan.json; do
|
||||
[ -f "$f" ] && uv run python -m api.diag.vuln "$f" || true
|
||||
done
|
||||
depends_on:
|
||||
- scan-notebooks
|
||||
- scan-zotero
|
||||
- scan-docs
|
||||
- scan-api
|
||||
|
||||
- name: deploy
|
||||
image: docker:cli
|
||||
environment:
|
||||
REGISTRY: *registry
|
||||
ORG: *org
|
||||
IMAGE_PREFIX: *image_prefix
|
||||
STACK_ROOT:
|
||||
from_secret: stack_root
|
||||
volumes:
|
||||
- /run/user/1000/docker.sock:/var/run/docker.sock
|
||||
- ${STACK_ROOT:-/home/kert/stack}:${STACK_ROOT:-/home/kert/stack}
|
||||
commands:
|
||||
- STACK_ROOT=${STACK_ROOT:-/home/kert/stack}
|
||||
- cd $STACK_ROOT
|
||||
- TAG=${CI_COMMIT_SHA:0:8}
|
||||
- for SVC in notebooks zotero docs api mc; do
|
||||
docker pull $REGISTRY/$ORG/$SVC:$TAG &&
|
||||
docker tag $REGISTRY/$ORG/$SVC:$TAG $IMAGE_PREFIX/$SVC:$TAG;
|
||||
done
|
||||
- sed -i "s/^COMMIT_SHA=.*/COMMIT_SHA=$TAG/" .env 2>/dev/null || echo "COMMIT_SHA=$TAG" >> .env
|
||||
- docker compose up -d --remove-orphans
|
||||
depends_on:
|
||||
- scan-notebooks
|
||||
- scan-zotero
|
||||
- scan-docs
|
||||
- scan-api
|
||||
- build-push-mc
|
||||
|
||||
# ── Failure reporter ─────────────────────────────────────────
|
||||
- name: report-failure
|
||||
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||
failure: ignore
|
||||
environment:
|
||||
<<: *diag_env
|
||||
commands:
|
||||
- uv sync --no-dev
|
||||
- uv run python -m api.diag
|
||||
when:
|
||||
- status: [failure]
|
||||
@@ -1,47 +0,0 @@
|
||||
# ── Release pipeline (generated by gen_config.py — woodpecker backend) ──
|
||||
# DO NOT EDIT — edit stack.toml and run gen_config.py
|
||||
|
||||
when:
|
||||
- event: tag
|
||||
|
||||
variables:
|
||||
- &diag_env
|
||||
UV_PYTHON_PREFERENCE: only-system
|
||||
UV_LINK_MODE: copy
|
||||
UV_PROJECT_ENVIRONMENT: .venv
|
||||
GITEA_TOKEN:
|
||||
from_secret: gitea_token
|
||||
|
||||
steps:
|
||||
- name: build-package
|
||||
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||
commands:
|
||||
- uv build --out-dir dist/
|
||||
- ls -lh dist/
|
||||
|
||||
- name: release
|
||||
image: woodpeckerci/plugin-gitea-release
|
||||
settings:
|
||||
api_key:
|
||||
from_secret: gitea_token
|
||||
base_url:
|
||||
from_secret: gitea_url
|
||||
files:
|
||||
- dist/*.whl
|
||||
- dist/*.tar.gz
|
||||
title: "${CI_COMMIT_TAG}"
|
||||
depends_on:
|
||||
- build-package
|
||||
|
||||
# ── Failure reporter ─────────────────────────────────────────
|
||||
- name: report-failure
|
||||
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
|
||||
failure: ignore
|
||||
environment:
|
||||
<<: *diag_env
|
||||
commands:
|
||||
- uv sync --no-dev
|
||||
- uv run python -m api.diag
|
||||
when:
|
||||
- status: [failure]
|
||||
|
||||
20
compose.yml
20
compose.yml
@@ -215,6 +215,25 @@ services:
|
||||
- woodpecker-server
|
||||
restart: unless-stopped
|
||||
|
||||
act-runner:
|
||||
image: gitea/act_runner:latest
|
||||
container_name: act-runner
|
||||
networks:
|
||||
- ci
|
||||
- storage
|
||||
privileged: true
|
||||
environment:
|
||||
- GITEA_INSTANCE_URL=http://gitea:3000
|
||||
- GITEA_RUNNER_REGISTRATION_TOKEN=${ACT_RUNNER_TOKEN}
|
||||
- GITEA_RUNNER_NAME=homelab-runner
|
||||
- GITEA_RUNNER_LABELS=ubuntu-latest:docker://catthehacker/ubuntu:act-latest
|
||||
volumes:
|
||||
- ${DOCKER_SOCK:-/run/user/1000/docker.sock}:/var/run/docker.sock
|
||||
- act_runner_data:/data
|
||||
depends_on:
|
||||
- gitea
|
||||
restart: unless-stopped
|
||||
|
||||
notebooks:
|
||||
image: ${IMAGE_PREFIX:-fhirworx}/notebooks:${COMMIT_SHA:-latest}
|
||||
container_name: notebooks
|
||||
@@ -586,6 +605,7 @@ volumes:
|
||||
gitea_config:
|
||||
woodpecker_data:
|
||||
woodpecker_agent_config:
|
||||
act_runner_data:
|
||||
loki_data:
|
||||
prometheus_data:
|
||||
grafana_data:
|
||||
|
||||
@@ -115,7 +115,7 @@ secret = "" # override via STACK_API_SECRET env var
|
||||
workers = 1
|
||||
|
||||
[ci]
|
||||
backend = "woodpecker"
|
||||
backend = "gitea"
|
||||
|
||||
[ci.woodpecker]
|
||||
plugin_buildx = "woodpeckerci/plugin-docker-buildx:5-insecure"
|
||||
|
||||
Reference in New Issue
Block a user