chore: drop deprecated Woodpecker references
Woodpecker CI is gone from the runtime; this purges the stale mentions in env/dev scripts, dashboards, homepages, CSS comments, and READMEs. Renames the SSO admin env var WOODPECKER_ADMIN to GITEA_ADMIN to match where the admin actually lives. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,10 +8,6 @@ GITEA_S3_ACCESS_KEY=changeme
|
|||||||
GITEA_S3_SECRET_KEY=changeme
|
GITEA_S3_SECRET_KEY=changeme
|
||||||
GITEA_DB_PASSWORD=changeme
|
GITEA_DB_PASSWORD=changeme
|
||||||
GITEA_TOKEN=changeme
|
GITEA_TOKEN=changeme
|
||||||
WOODPECKER_DB_PASSWORD=changeme
|
|
||||||
WOODPECKER_AGENT_SECRET=changeme
|
|
||||||
WOODPECKER_GITEA_CLIENT=changeme
|
|
||||||
WOODPECKER_GITEA_SECRET=changeme
|
|
||||||
|
|
||||||
# Nessie Data Lake
|
# Nessie Data Lake
|
||||||
NESSIE_DB_PASSWORD=changeme
|
NESSIE_DB_PASSWORD=changeme
|
||||||
@@ -49,8 +45,8 @@ S3_WAREHOUSE=s3://lakehouse/
|
|||||||
# ── Grafana ─────────────────────────────────────────
|
# ── Grafana ─────────────────────────────────────────
|
||||||
GF_ADMIN_PASSWORD=admin
|
GF_ADMIN_PASSWORD=admin
|
||||||
|
|
||||||
# ── Woodpecker ──────────────────────────────────────
|
# ── Gitea SSO ───────────────────────────────────────
|
||||||
WOODPECKER_ADMIN=kert
|
GITEA_ADMIN=kert
|
||||||
|
|
||||||
# ── PRISMA / LLM ───────────────────────────────────
|
# ── PRISMA / LLM ───────────────────────────────────
|
||||||
# Model-agnostic by design. Flip PRISMA_LLM_PROVIDER to "openai-compat"
|
# Model-agnostic by design. Flip PRISMA_LLM_PROVIDER to "openai-compat"
|
||||||
|
|||||||
34
README.md
34
README.md
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Healthcare analytics platform on self-hosted infrastructure. Replaces dbt SQL models with narwhals DataFrame-agnostic expression functions, backed by DuckDB locally and Iceberg/Trino in the lakehouse. 28 services, 14 data pipelines, 12,634 tests at 99% coverage.
|
Healthcare analytics platform on self-hosted infrastructure. Replaces dbt SQL models with narwhals DataFrame-agnostic expression functions, backed by DuckDB locally and Iceberg/Trino in the lakehouse. 29 services, 14 data pipelines, 13,844 tests at 99% coverage.
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ pip install stack[all] # everything
|
|||||||
pip install stack[aco,aws] # ACO analytics with AWS storage
|
pip install stack[aco,aws] # ACO analytics with AWS storage
|
||||||
```
|
```
|
||||||
|
|
||||||
14 modules available as optional extras: `aco`, `api`, `bcda`, `bib`, `bls`, `ccw`, `cli`, `cms`, `conf`, `opps`, `perf`, `pfs`, `rex`, `sem`. Cloud providers: `aws`, `azure`, `gcp`. Aggregates: `all`, `lake`.
|
17 modules available as optional extras: `aco`, `api`, `bcda`, `bib`, `bls`, `ccw`, `cli`, `cms`, `conf`, `mail`, `opps`, `perf`, `pfs`, `prisma`, `rec`, `rex`, `sem`. Cloud providers: `aws`, `azure`, `gcp`. Aggregates: `all`, `lake`.
|
||||||
|
|
||||||
## Services
|
## Services
|
||||||
|
|
||||||
@@ -128,19 +128,18 @@ Override context at runtime: `STACK_CONTEXT=lake` (or `aws`, `gcp`, `azure`).
|
|||||||
|
|
||||||
### Backend switching
|
### Backend switching
|
||||||
|
|
||||||
CI/CD workflows are auto-generated from `stack.toml` by `gen_config.py`. Three backends are supported:
|
CI/CD workflows are auto-generated from `stack.toml` by `gen_config.py`. Two backends are supported:
|
||||||
|
|
||||||
| Backend | Workflows directory | When to use |
|
| Backend | Workflows directory | When to use |
|
||||||
|---------|---------------------|-------------|
|
|---------|---------------------|-------------|
|
||||||
| `gitea` | `.gitea/workflows/` | Self-hosted Gitea instance (default) |
|
| `gitea` | `.gitea/workflows/` | Self-hosted Gitea instance (default) |
|
||||||
| `github` | `.github/workflows/` | GitHub repos / GitHub Actions |
|
| `github` | `.github/workflows/` | GitHub repos / GitHub Actions |
|
||||||
| `woodpecker` | `.woodpecker/` | Woodpecker CI server |
|
|
||||||
|
|
||||||
Switch backends by editing `stack.toml`:
|
Switch backends by editing `stack.toml`:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[ci]
|
[ci]
|
||||||
backend = "gitea" # change to "github" or "woodpecker"
|
backend = "gitea" # change to "github"
|
||||||
```
|
```
|
||||||
|
|
||||||
Then regenerate:
|
Then regenerate:
|
||||||
@@ -155,7 +154,7 @@ The generator reads image definitions from `stack.toml [images]`, dispatches to
|
|||||||
|
|
||||||
### Workflows
|
### Workflows
|
||||||
|
|
||||||
7 workflows generated per backend:
|
8 workflows generated per backend:
|
||||||
|
|
||||||
| Workflow | Trigger | What it does |
|
| Workflow | Trigger | What it does |
|
||||||
|----------|---------|--------------|
|
|----------|---------|--------------|
|
||||||
@@ -169,11 +168,11 @@ The generator reads image definitions from `stack.toml [images]`, dispatches to
|
|||||||
|
|
||||||
### Secret mapping
|
### Secret mapping
|
||||||
|
|
||||||
| Secret | Gitea | GitHub | Woodpecker |
|
| Secret | Gitea | GitHub |
|
||||||
|--------|-------|--------|------------|
|
|--------|-------|--------|
|
||||||
| Registry auth | `REGISTRY_USER` + `REGISTRY_TOKEN` | `GITHUB_TOKEN` (built-in) | `registry_username` + `registry_password` |
|
| Registry auth | `REGISTRY_USER` + `REGISTRY_TOKEN` | `GITHUB_TOKEN` (built-in) |
|
||||||
| Gitea API | `GITEA_TOKEN` | N/A | `gitea_token` |
|
| Gitea API | `GITEA_TOKEN` | N/A |
|
||||||
| Vuln reporting | `GITEA_TOKEN` | `GITHUB_TOKEN` | `gitea_token` |
|
| Vuln reporting | `GITEA_TOKEN` | `GITHUB_TOKEN` |
|
||||||
|
|
||||||
### Image tagging
|
### Image tagging
|
||||||
|
|
||||||
@@ -194,7 +193,7 @@ Daily automated pipeline (`pkg-supply-chain.yml`) that:
|
|||||||
|
|
||||||
## Credential management
|
## Credential management
|
||||||
|
|
||||||
All 20 service credentials derive from a single 256-bit root key via HKDF-SHA256. No passwords stored in `.env` — they regenerate deterministically from root key + commit SHA on each deploy.
|
All 16 service credentials derive from a single 256-bit root key via HKDF-SHA256. No passwords stored in `.env` — they regenerate deterministically from root key + commit SHA on each deploy.
|
||||||
|
|
||||||
```
|
```
|
||||||
ROOT_KEY + commit_sha -> HKDF-SHA256 -> all credentials -> .env + backends
|
ROOT_KEY + commit_sha -> HKDF-SHA256 -> all credentials -> .env + backends
|
||||||
@@ -418,7 +417,7 @@ The hook classifies staged files and runs only what is relevant:
|
|||||||
| `src/sem/*.py` | `tests/sem/` + `test_ast_coverage.py` | Module tests + structural invariants |
|
| `src/sem/*.py` | `tests/sem/` + `test_ast_coverage.py` | Module tests + structural invariants |
|
||||||
| `src/aco/*.py` + `src/sem/*.py` | `tests/aco/` + `tests/sem/` + structural | Both module test dirs |
|
| `src/aco/*.py` + `src/sem/*.py` | `tests/aco/` + `tests/sem/` + structural | Both module test dirs |
|
||||||
| `tests/bib/test_sync.py` | `tests/bib/` | Changed test dir |
|
| `tests/bib/test_sync.py` | `tests/bib/` | Changed test dir |
|
||||||
| `pyproject.toml` or `conftest.py` | Full suite (12,634+ tests) | Infrastructure change |
|
| `pyproject.toml` or `conftest.py` | Full suite (13,844+ tests) | Infrastructure change |
|
||||||
| `notebooks/pfs_calcs.py` | `marimo check` + notebook execution | Notebook validation only |
|
| `notebooks/pfs_calcs.py` | `marimo check` + notebook execution | Notebook validation only |
|
||||||
| `README.md` only | Nothing | No testable changes |
|
| `README.md` only | Nothing | No testable changes |
|
||||||
|
|
||||||
@@ -470,7 +469,7 @@ Dynamic values pulled from: `compose.yml` (services), `pyproject.toml` (modules)
|
|||||||
|
|
||||||
```
|
```
|
||||||
stack/
|
stack/
|
||||||
├── compose.yml Docker Compose (28 services)
|
├── compose.yml Docker Compose (29 services)
|
||||||
├── stack.toml Centralised configuration
|
├── stack.toml Centralised configuration
|
||||||
├── pyproject.toml Python project (uv, optional deps per module)
|
├── pyproject.toml Python project (uv, optional deps per module)
|
||||||
├── src/
|
├── src/
|
||||||
@@ -483,9 +482,12 @@ stack/
|
|||||||
│ ├── cli/ CLI entry point (typer)
|
│ ├── cli/ CLI entry point (typer)
|
||||||
│ ├── cms/ CMS public data tables
|
│ ├── cms/ CMS public data tables
|
||||||
│ ├── conf/ Config loader, storage abstraction, table base
|
│ ├── conf/ Config loader, storage abstraction, table base
|
||||||
|
│ ├── mail/
|
||||||
│ ├── opps/ Outpatient Prospective Payment System
|
│ ├── opps/ Outpatient Prospective Payment System
|
||||||
│ ├── perf/ Pipeline telemetry (OpenTelemetry)
|
│ ├── perf/ Pipeline telemetry (OpenTelemetry)
|
||||||
│ ├── pfs/ Physician Fee Schedule
|
│ ├── pfs/ Physician Fee Schedule
|
||||||
|
│ ├── prisma/
|
||||||
|
│ ├── rec/
|
||||||
│ ├── rex/ REX fixed-width file processing
|
│ ├── rex/ REX fixed-width file processing
|
||||||
│ ├── sem/ Semantic coverage orchestration
|
│ ├── sem/ Semantic coverage orchestration
|
||||||
│ └── zot/
|
│ └── zot/
|
||||||
@@ -497,7 +499,7 @@ stack/
|
|||||||
│ ├── loki/ Log aggregation
|
│ ├── loki/ Log aggregation
|
||||||
│ └── ... coredns, nginx, trino, polaris, rustfs, act-runner, gitea
|
│ └── ... coredns, nginx, trino, polaris, rustfs, act-runner, gitea
|
||||||
├── assets/ Branding, styles, generated artifacts
|
├── assets/ Branding, styles, generated artifacts
|
||||||
│ ├── css/ Per-service CSS (dashboard, gitea, marimo, woodpecker)
|
│ ├── css/ Per-service CSS (dashboard, grafana, marimo)
|
||||||
│ ├── icons/ Favicons, logos, coverage badge
|
│ ├── icons/ Favicons, logos, coverage badge
|
||||||
│ └── fhirworx.py fhirworx chart palette and Altair theme
|
│ └── fhirworx.py fhirworx chart palette and Altair theme
|
||||||
├── cloud/ Cloud provider deployment guides
|
├── cloud/ Cloud provider deployment guides
|
||||||
@@ -510,7 +512,7 @@ stack/
|
|||||||
│ ├── hooks/ Git hooks (tracked, core.hooksPath = dev/hooks)
|
│ ├── hooks/ Git hooks (tracked, core.hooksPath = dev/hooks)
|
||||||
│ ├── seeds/ Reference data (BCDA samples, CMS docs)
|
│ ├── seeds/ Reference data (BCDA samples, CMS docs)
|
||||||
│ └── pipelines/ CI-agnostic pipeline specs
|
│ └── pipelines/ CI-agnostic pipeline specs
|
||||||
├── tests/ 12,634 tests at 99% coverage
|
├── tests/ 13,844 tests at 99% coverage
|
||||||
├── notebooks/ Marimo notebooks
|
├── notebooks/ Marimo notebooks
|
||||||
├── docs/ Docusaurus site
|
├── docs/ Docusaurus site
|
||||||
├── data/ DuckDB, bib.sqlite, BCDA/CMS data, zotero (gitignored)
|
├── data/ DuckDB, bib.sqlite, BCDA/CMS data, zotero (gitignored)
|
||||||
|
|||||||
17
README.md.j2
17
README.md.j2
@@ -121,19 +121,18 @@ Override context at runtime: `STACK_CONTEXT=lake` (or `aws`, `gcp`, `azure`).
|
|||||||
|
|
||||||
### Backend switching
|
### Backend switching
|
||||||
|
|
||||||
CI/CD workflows are auto-generated from `stack.toml` by `gen_config.py`. Three backends are supported:
|
CI/CD workflows are auto-generated from `stack.toml` by `gen_config.py`. Two backends are supported:
|
||||||
|
|
||||||
| Backend | Workflows directory | When to use |
|
| Backend | Workflows directory | When to use |
|
||||||
|---------|---------------------|-------------|
|
|---------|---------------------|-------------|
|
||||||
| `gitea` | `.gitea/workflows/` | Self-hosted Gitea instance (default) |
|
| `gitea` | `.gitea/workflows/` | Self-hosted Gitea instance (default) |
|
||||||
| `github` | `.github/workflows/` | GitHub repos / GitHub Actions |
|
| `github` | `.github/workflows/` | GitHub repos / GitHub Actions |
|
||||||
| `woodpecker` | `.woodpecker/` | Woodpecker CI server |
|
|
||||||
|
|
||||||
Switch backends by editing `stack.toml`:
|
Switch backends by editing `stack.toml`:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[ci]
|
[ci]
|
||||||
backend = "gitea" # change to "github" or "woodpecker"
|
backend = "gitea" # change to "github"
|
||||||
```
|
```
|
||||||
|
|
||||||
Then regenerate:
|
Then regenerate:
|
||||||
@@ -162,11 +161,11 @@ The generator reads image definitions from `stack.toml [images]`, dispatches to
|
|||||||
|
|
||||||
### Secret mapping
|
### Secret mapping
|
||||||
|
|
||||||
| Secret | Gitea | GitHub | Woodpecker |
|
| Secret | Gitea | GitHub |
|
||||||
|--------|-------|--------|------------|
|
|--------|-------|--------|
|
||||||
| Registry auth | `REGISTRY_USER` + `REGISTRY_TOKEN` | `GITHUB_TOKEN` (built-in) | `registry_username` + `registry_password` |
|
| Registry auth | `REGISTRY_USER` + `REGISTRY_TOKEN` | `GITHUB_TOKEN` (built-in) |
|
||||||
| Gitea API | `GITEA_TOKEN` | N/A | `gitea_token` |
|
| Gitea API | `GITEA_TOKEN` | N/A |
|
||||||
| Vuln reporting | `GITEA_TOKEN` | `GITHUB_TOKEN` | `gitea_token` |
|
| Vuln reporting | `GITEA_TOKEN` | `GITHUB_TOKEN` |
|
||||||
|
|
||||||
### Image tagging
|
### Image tagging
|
||||||
|
|
||||||
@@ -478,7 +477,7 @@ stack/
|
|||||||
│ ├── loki/ Log aggregation
|
│ ├── loki/ Log aggregation
|
||||||
│ └── ... coredns, nginx, trino, polaris, rustfs, act-runner, gitea
|
│ └── ... coredns, nginx, trino, polaris, rustfs, act-runner, gitea
|
||||||
├── assets/ Branding, styles, generated artifacts
|
├── assets/ Branding, styles, generated artifacts
|
||||||
│ ├── css/ Per-service CSS (dashboard, gitea, marimo, woodpecker)
|
│ ├── css/ Per-service CSS (dashboard, grafana, marimo)
|
||||||
│ ├── icons/ Favicons, logos, coverage badge
|
│ ├── icons/ Favicons, logos, coverage badge
|
||||||
│ └── fhirworx.py fhirworx chart palette and Altair theme
|
│ └── fhirworx.py fhirworx chart palette and Altair theme
|
||||||
├── cloud/ Cloud provider deployment guides
|
├── cloud/ Cloud provider deployment guides
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
Inspired by ProPublica, The Marshall Project, and the Federal Register
|
Inspired by ProPublica, The Marshall Project, and the Federal Register
|
||||||
|
|
||||||
When changing a token here, propagate to the service-specific files:
|
When changing a token here, propagate to the service-specific files:
|
||||||
inject.css, dashboard.css, gitea.css, woodpecker.css, marimo.css */
|
inject.css, dashboard.css, grafana.css, marimo.css */
|
||||||
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;600;700&family=Source+Serif+4:ital,wght@0,300;0,400;0,600;1,400&family=JetBrains+Mono:wght@400;500;600&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;600;700&family=Source+Serif+4:ital,wght@0,300;0,400;0,600;1,400&family=JetBrains+Mono:wght@400;500;600&display=swap');
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
Universal injectable CSS.
|
Universal injectable CSS.
|
||||||
Injected via Traefik rewrite-body plugin into:
|
Injected via Traefik rewrite-body plugin into:
|
||||||
Grafana, Traefik Dashboard, RustFS/MinIO, Jaeger, Prometheus, Trino
|
Grafana, Traefik Dashboard, RustFS/MinIO, Jaeger, Prometheus, Trino
|
||||||
Palette matches: Gitea, Woodpecker, Marimo, nginx dashboard themes */
|
Palette matches: Gitea, Marimo, nginx dashboard themes */
|
||||||
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;600;700&family=Source+Serif+4:ital,wght@0,300;0,400;0,600;1,400&family=JetBrains+Mono:wght@400;500;600&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;600;700&family=Source+Serif+4:ital,wght@0,300;0,400;0,600;1,400&family=JetBrains+Mono:wght@400;500;600&display=swap');
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ Docker Compose on a single node with Traefik ingress.
|
|||||||
| Iceberg Catalog | Nessie / Polaris | `[lake.nessie]`, `[lake.polaris]` |
|
| Iceberg Catalog | Nessie / Polaris | `[lake.nessie]`, `[lake.polaris]` |
|
||||||
| Query Engine | Trino | `[lake.trino]` |
|
| Query Engine | Trino | `[lake.trino]` |
|
||||||
| Ingress | Traefik | infra/traefik/ |
|
| Ingress | Traefik | infra/traefik/ |
|
||||||
| CI/CD | Gitea Actions + Woodpecker| `[ci]` in stack.toml |
|
| CI/CD | Gitea Actions | `[ci]` in stack.toml |
|
||||||
| Observability | Grafana + Prometheus + Loki + Jaeger | compose.yml |
|
| Observability | Grafana + Prometheus + Loki + Jaeger | compose.yml |
|
||||||
| DNS | CoreDNS | infra/coredns/ |
|
| DNS | CoreDNS | infra/coredns/ |
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# CI-agnostic pipeline definition for package supply chain management.
|
# CI-agnostic pipeline definition for package supply chain management.
|
||||||
# This is the abstract spec — use gen_config.py to emit concrete workflow
|
# This is the abstract spec — use gen_config.py to emit concrete workflow
|
||||||
# files for Gitea Actions, Woodpecker, and GitHub Actions.
|
# files for Gitea Actions and GitHub Actions.
|
||||||
#
|
#
|
||||||
# Pipeline: inventory → mirror-sync → drift-check → vuln-scan → issue-create
|
# Pipeline: inventory → mirror-sync → drift-check → vuln-scan → issue-create
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"""GitHub Actions workflow emitter.
|
"""GitHub Actions workflow emitter.
|
||||||
|
|
||||||
Generates .github/workflows/*.yml from the same image definitions
|
Generates .github/workflows/*.yml from the same image definitions
|
||||||
used by the Woodpecker backend. All output is valid GitHub Actions YAML.
|
used by the Gitea Actions backend. All output is valid GitHub Actions YAML.
|
||||||
|
|
||||||
Usage (called by gen_config.py)::
|
Usage (called by gen_config.py)::
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ GRAFANA_ENV = STATE / "grafana.env"
|
|||||||
|
|
||||||
DOMAIN = os.environ.get("DOMAIN", "fhirworx.io")
|
DOMAIN = os.environ.get("DOMAIN", "fhirworx.io")
|
||||||
GITEA_API = os.environ.get("GITEA_API", "http://git:3000/api/v1")
|
GITEA_API = os.environ.get("GITEA_API", "http://git:3000/api/v1")
|
||||||
ADMIN_USER = os.environ.get("WOODPECKER_ADMIN", "kert")
|
ADMIN_USER = os.environ.get("GITEA_ADMIN", "kert")
|
||||||
ADMIN_PASS = os.environ.get("GITEA_ADMIN_PASSWORD", "")
|
ADMIN_PASS = os.environ.get("GITEA_ADMIN_PASSWORD", "")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
"uid": "loki"
|
"uid": "loki"
|
||||||
},
|
},
|
||||||
"editorMode": "code",
|
"editorMode": "code",
|
||||||
"expr": "{container_name=~\"gitea|woodpecker.*\"} |= ``",
|
"expr": "{container_name=~\"gitea.*\"} |= ``",
|
||||||
"queryType": "range",
|
"queryType": "range",
|
||||||
"refId": "A"
|
"refId": "A"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -294,16 +294,6 @@
|
|||||||
<div class="stripe"></div>
|
<div class="stripe"></div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a data-subdomain="ci" target="_blank" class="tile ci">
|
|
||||||
<span class="status-dot"></span>
|
|
||||||
<span class="icon">🔨</span>
|
|
||||||
<div class="tile-eyebrow">CI/CD</div>
|
|
||||||
<div class="tile-title">Woodpecker</div>
|
|
||||||
<p class="tile-desc">Simple yet powerful CI/CD engine</p>
|
|
||||||
<span class="tile-port"></span>
|
|
||||||
<div class="stripe"></div>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a data-subdomain="notebooks" target="_blank" class="tile notebook">
|
<a data-subdomain="notebooks" target="_blank" class="tile notebook">
|
||||||
<span class="tile-badge gpu">GPU</span>
|
<span class="tile-badge gpu">GPU</span>
|
||||||
<span class="status-dot"></span>
|
<span class="status-dot"></span>
|
||||||
|
|||||||
@@ -61,16 +61,6 @@
|
|||||||
<div class="stripe"></div>
|
<div class="stripe"></div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a data-subdomain="ci" target="_blank" class="tile ci">
|
|
||||||
<span class="status"></span>
|
|
||||||
<span class="icon">🔨</span>
|
|
||||||
<div class="tile-eyebrow">CI/CD</div>
|
|
||||||
<div class="tile-title">Woodpecker</div>
|
|
||||||
<p class="tile-desc">Simple yet powerful CI/CD engine</p>
|
|
||||||
<span class="tile-port"></span>
|
|
||||||
<div class="stripe"></div>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a data-subdomain="notebooks" target="_blank" class="tile notebook">
|
<a data-subdomain="notebooks" target="_blank" class="tile notebook">
|
||||||
<span class="badge gpu">GPU</span>
|
<span class="badge gpu">GPU</span>
|
||||||
<span class="status"></span>
|
<span class="status"></span>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"""Backend-agnostic CI failure reporter.
|
"""Backend-agnostic CI failure reporter.
|
||||||
|
|
||||||
Files a Gitea issue when any CI workflow step fails, regardless of
|
Files a Gitea issue when any CI workflow step fails, regardless of
|
||||||
whether the CI backend is Gitea Actions, GitHub Actions, or Woodpecker.
|
whether the CI backend is Gitea Actions or GitHub Actions.
|
||||||
|
|
||||||
Usage from workflow YAML::
|
Usage from workflow YAML::
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user