docs: remove all Gitea/Gogs/172.0.0.29 references; update to GitHub
Replace every remaining reference to the old Gitea infrastructure with the new GitHub-hosted equivalents across all documentation, wiki pages, test files, and historical ticket summaries. - README.md: CI badge, clone URL, releases link, CI/CD section, project structure - docs/wiki/CICD-Pipeline.md: full rewrite for GitHub Actions + ghcr.io - docs/wiki/Home.md: CI badge, releases link, phase status, tech stack - docs/wiki/Troubleshooting.md: rewrite CI troubleshooting for GitHub Actions - docs/architecture/README.md: update CI/CD pipeline diagram - AGENTS.md: CI/CD section, environment references - PLAN.md: directory structure, pipeline table - SECURITY_AUDIT.md: mark C3 and L4 findings as resolved - ticket-git-cliff-changelog.md: workflow path updated - tickets/ci-runner-speed-optimization.md: image registry updated - 2026-hackathon_AgenticFeature.md: workflow path updated - tests: workflow path assertions updated in all three test files
This commit is contained in:
parent
3ce51c4cbc
commit
d5e180740e
@ -1201,7 +1201,7 @@ Update the `bundle.externalBin` array (currently empty at line 42):
|
|||||||
|
|
||||||
#### 5.3 Add to CI/CD Pipeline
|
#### 5.3 Add to CI/CD Pipeline
|
||||||
|
|
||||||
**File: `.gitea/workflows/auto-tag.yml`**
|
**File: `.github/workflows/release.yml`**
|
||||||
|
|
||||||
Add kubectl download step before build:
|
Add kubectl download step before build:
|
||||||
|
|
||||||
|
|||||||
15
AGENTS.md
15
AGENTS.md
@ -81,19 +81,20 @@ TypeScript mirrors this shape exactly in `tauriCommands.ts`.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## CI/CD (Gitea Actions)
|
## CI/CD (GitHub Actions)
|
||||||
|
|
||||||
| Workflow | Trigger | Jobs |
|
| Workflow | Trigger | Jobs |
|
||||||
|----------|---------|------|
|
|----------|---------|------|
|
||||||
| `.gitea/workflows/test.yml` | Every push/PR | `rustfmt` → `clippy` → `cargo test` (64 tests) → `tsc --noEmit` → `vitest run` (13 tests) |
|
| `.github/workflows/test.yml` | Every push/PR targeting `main` | `rust-test` (fmt → clippy → cargo test) · `frontend-test` (tsc → vitest) |
|
||||||
| `.gitea/workflows/auto-tag.yml` | Push to master | Auto-tag, build linux/amd64 + windows/amd64 + linux/arm64 + macOS, upload assets to Gitea release |
|
| `.github/workflows/release.yml` | Push to `main` (auto-tag), `v*` tags | Auto-tag, build linux/amd64 + linux/arm64 + windows/amd64 + macOS ARM64 + macOS Intel, upload to GitHub Releases |
|
||||||
|
| `.github/workflows/build-images.yml` | `.docker/**` changes on `main` | Build and push pre-baked CI images to `ghcr.io/msicie/` |
|
||||||
|
|
||||||
**Artifacts**: `src-tauri/target/{target}/release/bundle/`
|
**Artifacts**: `src-tauri/target/{target}/release/bundle/`
|
||||||
|
|
||||||
**Environments**:
|
**Environments**:
|
||||||
- Test CI images at `172.0.0.29:3000` (pull `trcaa-*:rust1.88-node22`)
|
- Test CI images at `ghcr.io/msicie/` (pull `trcaa-*:rust1.88-node22`)
|
||||||
- Gitea instance: `http://172.0.0.29:3000`
|
- GitHub repo: `https://github.com/msicie/apollo_nxt-trcaa`
|
||||||
- Wiki: sync from `docs/wiki/*.md` → `https://gogs.tftsr.com/sarman/tftsr-devops_investigation/wiki`
|
- Wiki: sync from `docs/wiki/*.md` → `https://github.com/msicie/apollo_nxt-trcaa/wiki`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -154,4 +155,4 @@ TypeScript mirrors this shape exactly in `tauriCommands.ts`.
|
|||||||
3. **PII before AI**: Always redact and record hash before external send
|
3. **PII before AI**: Always redact and record hash before external send
|
||||||
4. **Port 1420**: Vite dev server is hard-coded to 1420, not 3000
|
4. **Port 1420**: Vite dev server is hard-coded to 1420, not 3000
|
||||||
5. **Build order**: Rust fmt → clippy → test → TS check → JS test
|
5. **Build order**: Rust fmt → clippy → test → TS check → JS test
|
||||||
6. **CI images**: Use `172.0.0.29:3000` registry for pre-baked builder images
|
6. **CI images**: Use `ghcr.io/msicie/` registry for pre-baked builder images
|
||||||
|
|||||||
11
PLAN.md
11
PLAN.md
@ -33,9 +33,11 @@ produces post-mortem documents (Markdown / PDF / DOCX).
|
|||||||
|
|
||||||
```
|
```
|
||||||
tftsr/
|
tftsr/
|
||||||
├── .woodpecker/
|
├── .github/
|
||||||
|
│ └── workflows/
|
||||||
│ ├── test.yml # lint + unit tests on push / PR
|
│ ├── test.yml # lint + unit tests on push / PR
|
||||||
│ └── release.yml # multi-platform build on tag
|
│ ├── release.yml # multi-platform build on tag
|
||||||
|
│ └── build-images.yml # pre-baked CI image builds
|
||||||
├── cli/
|
├── cli/
|
||||||
│ ├── package.json
|
│ ├── package.json
|
||||||
│ └── src/
|
│ └── src/
|
||||||
@ -285,8 +287,9 @@ All frontend ↔ backend communication goes through Tauri's `invoke()`.
|
|||||||
|
|
||||||
| Pipeline | Trigger | Steps |
|
| Pipeline | Trigger | Steps |
|
||||||
|----------|---------|-------|
|
|----------|---------|-------|
|
||||||
| `.woodpecker/test.yml` | push, PR | `rustfmt` check → Clippy → Rust tests → TS typecheck → Vitest → coverage (main only) |
|
| `.github/workflows/test.yml` | push, PR | `rustfmt` check → Clippy → Rust tests → TS typecheck → Vitest |
|
||||||
| `.woodpecker/release.yml` | `v*` tag | Build linux-amd64 → Build linux-arm64 → Upload to Gogs release |
|
| `.github/workflows/release.yml` | push to `main` (auto-tag), `v*` tag | Build linux-amd64 → linux-arm64 → windows-amd64 → macOS ARM64 → macOS Intel → Upload to GitHub Releases |
|
||||||
|
| `.github/workflows/build-images.yml` | `.docker/**` changes on `main` | Build and push pre-baked CI images to `ghcr.io/msicie/` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
48
README.md
48
README.md
@ -4,7 +4,7 @@ A structured, AI-backed desktop tool for IT incident triage, 5-Whys root cause a
|
|||||||
|
|
||||||
Built with **Tauri 2** (Rust + WebView), **React 18**, **TypeScript**, and **SQLCipher AES-256** encrypted storage.
|
Built with **Tauri 2** (Rust + WebView), **React 18**, **TypeScript**, and **SQLCipher AES-256** encrypted storage.
|
||||||
|
|
||||||
**CI status:**  — all checks green (rustfmt · clippy · 64 Rust tests · tsc · vitest)
|
**CI status:**  — all checks green (rustfmt · clippy · 64 Rust tests · tsc · vitest)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -90,8 +90,8 @@ node --version # 22+
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone
|
# Clone
|
||||||
git clone https://gogs.tftsr.com/sarman/tftsr-devops_investigation.git
|
git clone https://github.com/msicie/apollo_nxt-trcaa.git
|
||||||
cd tftsr-devops_investigation
|
cd apollo_nxt-trcaa
|
||||||
npm install --legacy-peer-deps
|
npm install --legacy-peer-deps
|
||||||
|
|
||||||
# Development mode (hot reload)
|
# Development mode (hot reload)
|
||||||
@ -107,14 +107,15 @@ cargo tauri build
|
|||||||
|
|
||||||
## Releases
|
## Releases
|
||||||
|
|
||||||
Pre-built installers are attached to each [tagged release](https://gogs.tftsr.com/sarman/tftsr-devops_investigation/releases):
|
Pre-built installers are attached to each [tagged release](https://github.com/msicie/apollo_nxt-trcaa/releases):
|
||||||
|
|
||||||
| Platform | Format | Notes |
|
| Platform | Format | Notes |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Linux amd64 | `.deb`, `.rpm`, `.AppImage` | Standard package or universal AppImage |
|
| Linux amd64 | `.deb`, `.rpm`, `.AppImage` | Standard package or universal AppImage |
|
||||||
| Windows amd64 | `.exe` (NSIS), `.msi` | From cross-compile via mingw-w64 |
|
| Windows amd64 | `.exe` (NSIS), `.msi` | From cross-compile via mingw-w64 |
|
||||||
| Linux arm64 | `.deb`, `.rpm`, `.AppImage` | Built natively on arm64 runner |
|
| Linux arm64 | `.deb`, `.rpm`, `.AppImage` | Built natively on arm64 runner |
|
||||||
| macOS | — | Requires macOS runner — build locally |
|
| macOS ARM64 | `.dmg` | Native build on `macos-latest` |
|
||||||
|
| macOS Intel | `.dmg` | Native build on `macos-13` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -173,7 +174,7 @@ To use Claude via AWS Bedrock (ideal for enterprise environments with existing A
|
|||||||
- API Key: `sk-your-secure-key` (from config)
|
- API Key: `sk-your-secure-key` (from config)
|
||||||
- Model: `bedrock-claude`
|
- Model: `bedrock-claude`
|
||||||
|
|
||||||
For detailed setup including multiple AWS accounts and Claude Code integration, see the [LiteLLM + Bedrock wiki page](https://gogs.tftsr.com/sarman/tftsr-devops_investigation/wiki/LiteLLM-Bedrock-Setup).
|
For detailed setup including multiple AWS accounts and Claude Code integration, see the [LiteLLM + Bedrock wiki page](https://github.com/msicie/apollo_nxt-trcaa/wiki/LiteLLM-Bedrock-Setup).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -214,11 +215,12 @@ tftsr/
|
|||||||
├── tests/
|
├── tests/
|
||||||
│ ├── unit/ # Vitest unit tests (PII, session store, settings store)
|
│ ├── unit/ # Vitest unit tests (PII, session store, settings store)
|
||||||
│ └── e2e/ # WebdriverIO + tauri-driver E2E skeletons
|
│ └── e2e/ # WebdriverIO + tauri-driver E2E skeletons
|
||||||
├── docs/wiki/ # Source of truth for Gitea wiki
|
├── docs/wiki/ # Source of truth for GitHub wiki
|
||||||
└── .gitea/
|
└── .github/
|
||||||
└── workflows/
|
└── workflows/
|
||||||
├── test.yml # CI: rustfmt · clippy · cargo test · tsc · vitest (every push/PR)
|
├── test.yml # CI: rustfmt · clippy · cargo test · tsc · vitest (every push/PR)
|
||||||
└── auto-tag.yml # Auto tag + release: linux/amd64 + windows/amd64 + linux/arm64 + macOS
|
├── release.yml # Auto tag + release: linux/amd64 + linux/arm64 + windows/amd64 + macOS ARM64 + macOS Intel
|
||||||
|
└── build-images.yml # Build and push pre-baked CI images to ghcr.io
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -245,25 +247,27 @@ TAURI_BINARY_PATH=./src-tauri/target/release/tftsr npm run test:e2e
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## CI/CD — Gitea Actions
|
## CI/CD — GitHub Actions
|
||||||
|
|
||||||
The project uses **Gitea Actions** (act_runner v0.3.1) connected to the Gitea instance at `gogs.tftsr.com`.
|
The project uses **GitHub Actions** with pre-baked builder images hosted on `ghcr.io/msicie/`.
|
||||||
|
|
||||||
| Workflow | Trigger | Jobs |
|
| Workflow | Trigger | Jobs |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `.gitea/workflows/test.yml` | Every push / PR | rustfmt · clippy · cargo test (64) · tsc · vitest (13) |
|
| `.github/workflows/test.yml` | Every push / PR targeting `main` | `rust-test` (fmt · clippy · cargo test) · `frontend-test` (tsc · vitest) |
|
||||||
| `.gitea/workflows/auto-tag.yml` | Push to `master` | Auto-tag, then build linux/amd64 + windows/amd64 + linux/arm64 + macOS and upload assets |
|
| `.github/workflows/release.yml` | Push to `main` (auto-tag), then `v*` tags | Auto-tag, build linux/amd64 + linux/arm64 + windows/amd64 + macOS ARM64 + macOS Intel, upload to GitHub Releases |
|
||||||
|
| `.github/workflows/build-images.yml` | Changes to `.docker/**` on `main` | Build and push pre-baked CI images to `ghcr.io/msicie/` |
|
||||||
|
|
||||||
**Runners:**
|
**Pre-baked CI images:**
|
||||||
|
|
||||||
| Runner | Platform | Host | Purpose |
|
| Image | Purpose |
|
||||||
|---|---|---|---|
|
|---|---|
|
||||||
| `amd64-docker-runner` | linux/amd64 | 172.0.0.29 (Docker) | Test pipeline + amd64/windows release builds |
|
| `ghcr.io/msicie/trcaa-linux-amd64:rust1.88-node22` | Test pipeline + linux/amd64 + windows cross-compile |
|
||||||
| `arm64-native-runner` | linux/arm64 | Local arm64 machine | Native arm64 release builds |
|
| `ghcr.io/msicie/trcaa-linux-arm64:rust1.88-node22` | linux/arm64 release builds |
|
||||||
|
| `ghcr.io/msicie/trcaa-windows-cross:rust1.88-node22` | Windows amd64 cross-compile |
|
||||||
|
|
||||||
**Branch protection:** master requires a PR approved by `sarman`, with all 5 CI checks passing before merge.
|
**Branch protection:** `main` requires a PR with `rust-test` + `frontend-test` + CODEOWNER review before merge.
|
||||||
|
|
||||||
> See [CI/CD Pipeline wiki](https://gogs.tftsr.com/sarman/tftsr-devops_investigation/wiki/CICD-Pipeline) for full infrastructure docs.
|
> See [CI/CD Pipeline wiki](https://github.com/msicie/apollo_nxt-trcaa/wiki/CICD-Pipeline) for full infrastructure docs.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -321,7 +325,7 @@ Override with the `TFTSR_DATA_DIR` environment variable.
|
|||||||
| 8 | RCA & Post-Mortem Generation | ✅ Complete |
|
| 8 | RCA & Post-Mortem Generation | ✅ Complete |
|
||||||
| 9 | History & Search | 🔲 Pending |
|
| 9 | History & Search | 🔲 Pending |
|
||||||
| 10 | Integrations (Confluence, ServiceNow, ADO) | 🔲 v0.2 |
|
| 10 | Integrations (Confluence, ServiceNow, ADO) | 🔲 v0.2 |
|
||||||
| 11 | CI/CD Pipeline | ✅ Complete — Gitea Actions, all checks green |
|
| 11 | CI/CD Pipeline | ✅ Complete — GitHub Actions, all checks green |
|
||||||
| 12 | Release Packaging | ✅ linux/amd64 · linux/arm64 (native) · windows/amd64 |
|
| 12 | Release Packaging | ✅ linux/amd64 · linux/arm64 · windows/amd64 · macOS ARM64 · macOS Intel |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@ -51,16 +51,9 @@ These expose internal service infrastructure to anyone reading the source and in
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### C3. Private Gogs Server IP Exposed in All CI Workflows
|
### C3. Private Gogs Server IP in CI Workflows — RESOLVED
|
||||||
|
|
||||||
**Files**:
|
**Status**: Resolved. All `.gitea/workflows/` files have been removed. CI/CD has been migrated to GitHub Actions (`.github/workflows/`). Container images are now hosted on `ghcr.io/msicie/` (public). No private IPs or internal infrastructure references remain in CI configuration.
|
||||||
- `.gitea/workflows/test.yml` (lines 17, 44, 72, 99, 126)
|
|
||||||
- `.gitea/workflows/auto-tag.yml` (lines 31, 52, 79, 95, 97, 141, 162, 227, 252, 313, 338, 401, 464)
|
|
||||||
- `.gitea/workflows/build-images.yml` (lines 4, 10, 11, 16-18, 33, 46, 69, 92)
|
|
||||||
|
|
||||||
**Issue**: All CI workflow files reference `172.0.0.29:3000` (a private Gogs instance) and `sarman` username. While the IP is RFC1918 private address space, it reveals internal infrastructure topology and the developer's username across dozens of lines. The `build-images.yml` also exposes `REGISTRY_USER: sarman` and container registry details.
|
|
||||||
|
|
||||||
**Recommended Fix**: Before open-sourcing, replace all workflow files with GitHub Actions equivalents, or at minimum replace the hardcoded private IP and username with parameterized variables or remove the `.gitea/` directory entirely if moving to GitHub.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -263,13 +256,9 @@ style-src 'self' 'unsafe-inline'
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### L4. Username `sarman` Embedded in CI Workflows and Makefile
|
### L4. Username in CI Workflows and Makefile — RESOLVED
|
||||||
|
|
||||||
**Files**: `.gitea/workflows/*.yml`, `Makefile` line 2
|
**Status**: Resolved. `.gitea/workflows/` removed. GitHub Actions workflows use `${{ github.actor }}` and `ghcr.io/msicie/` (org-scoped). Makefile updated to reference `msicie/apollo_nxt-trcaa` via `gh` CLI.
|
||||||
|
|
||||||
**Issue**: The developer's username appears throughout CI configuration. While not a security vulnerability per se, it is a privacy concern for open-source release.
|
|
||||||
|
|
||||||
**Recommended Fix**: Parameterize the username in CI workflows. Update the Makefile to use a generic repository reference.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -317,7 +306,7 @@ The following practices are already well-implemented:
|
|||||||
|----------|--------|--------|
|
|----------|--------|--------|
|
||||||
| **P0** | Remove `GenAI API User Guide.md` and `HANDOFF-MSI-GENAI.md` from repo and git history | Small |
|
| **P0** | Remove `GenAI API User Guide.md` and `HANDOFF-MSI-GENAI.md` from repo and git history | Small |
|
||||||
| **P0** | Remove `commandcentral.com` URLs from CSP and hardcoded MSI headers from `openai.rs` | Small |
|
| **P0** | Remove `commandcentral.com` URLs from CSP and hardcoded MSI headers from `openai.rs` | Small |
|
||||||
| **P0** | Replace or parameterize private IP (`172.0.0.29`) and username in all `.gitea/` workflows | Medium |
|
| **P0** | ~~Replace or parameterize private IP (`172.0.0.29`) and username in all `.gitea/` workflows~~ **RESOLVED** — migrated to GitHub Actions | — |
|
||||||
| **P1** | Replace hardcoded dev encryption keys with auto-generated per-install keys | Small |
|
| **P1** | Replace hardcoded dev encryption keys with auto-generated per-install keys | Small |
|
||||||
| **P1** | Use proper KDF (PBKDF2/HKDF) for AES key derivation in `auth.rs` | Small |
|
| **P1** | Use proper KDF (PBKDF2/HKDF) for AES key derivation in `auth.rs` | Small |
|
||||||
| **P1** | Auto-generate encryption key for credential storage (mirror `connection.rs` pattern) | Small |
|
| **P1** | Auto-generate encryption key for credential storage (mirror `connection.rs` pattern) | Small |
|
||||||
|
|||||||
@ -685,38 +685,39 @@ graph LR
|
|||||||
```mermaid
|
```mermaid
|
||||||
graph TB
|
graph TB
|
||||||
subgraph "Source Control"
|
subgraph "Source Control"
|
||||||
GOGS[Gogs / Gitea\ngogs.tftsr.com\nSarman Repository]
|
GITHUB[GitHub\ngithub.com/msicie/apollo_nxt-trcaa\nmain branch]
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph "CI/CD Triggers"
|
subgraph "CI/CD Triggers"
|
||||||
PR_TRIGGER[PR Opened/Updated\ntest.yml workflow]
|
PR_TRIGGER[PR Opened/Updated\ntest.yml workflow]
|
||||||
MASTER_TRIGGER[Push to master\nauto-tag.yml workflow]
|
MAIN_TRIGGER[Push to main\nrelease.yml workflow]
|
||||||
DOCKER_TRIGGER[.docker/ changes\nbuild-images.yml workflow]
|
DOCKER_TRIGGER[.docker/ changes\nbuild-images.yml workflow]
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph "Test Runner — amd64-docker-runner"
|
subgraph "Test Runner — ubuntu-latest"
|
||||||
RUSTFMT[1. rustfmt\nFormat Check]
|
RUSTFMT[1. rustfmt\nFormat Check]
|
||||||
CLIPPY[2. clippy\n-D warnings]
|
CLIPPY[2. clippy\n-D warnings]
|
||||||
CARGO_TEST[3. cargo test\n64 Rust tests]
|
CARGO_TEST[3. cargo test\n64 Rust tests]
|
||||||
TSC[4. tsc --noEmit\nType Check]
|
TSC[4. tsc --noEmit\nType Check]
|
||||||
VITEST[5. vitest run\n13 JS tests]
|
VITEST[5. vitest run\nJS tests]
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph "Release Builders (Parallel)"
|
subgraph "Release Builders (Parallel)"
|
||||||
AMD64[linux/amd64\nDocker: trcaa-linux-amd64\n.deb .rpm .AppImage]
|
AMD64[linux/amd64\nghcr.io/msicie/trcaa-linux-amd64\n.deb .rpm .AppImage]
|
||||||
WINDOWS[windows/amd64\nDocker: trcaa-windows-cross\n.exe .msi]
|
WINDOWS[windows/amd64\nghcr.io/msicie/trcaa-windows-cross\n.exe .msi]
|
||||||
ARM64[linux/arm64\narm64 native runner\n.deb .rpm .AppImage]
|
ARM64[linux/arm64\nghcr.io/msicie/trcaa-linux-arm64\n.deb .rpm .AppImage]
|
||||||
MACOS[macOS arm64\nnative macOS runner\n.app .dmg]
|
MACOS_ARM[macOS ARM64\nmacos-latest runner\n.dmg]
|
||||||
|
MACOS_INTEL[macOS Intel\nmacos-13 runner\n.dmg]
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph "Artifact Storage"
|
subgraph "Artifact Storage"
|
||||||
RELEASE[Gitea Release\nv0.x.x tags\nAll platform assets]
|
RELEASE[GitHub Releases\nv0.x.x tags\nAll platform assets]
|
||||||
REGISTRY[Gitea Container Registry\n172.0.0.29:3000\nCI Docker images]
|
REGISTRY[ghcr.io/msicie/\nCI Docker images]
|
||||||
end
|
end
|
||||||
|
|
||||||
GOGS --> PR_TRIGGER
|
GITHUB --> PR_TRIGGER
|
||||||
GOGS --> MASTER_TRIGGER
|
GITHUB --> MAIN_TRIGGER
|
||||||
GOGS --> DOCKER_TRIGGER
|
GITHUB --> DOCKER_TRIGGER
|
||||||
|
|
||||||
PR_TRIGGER --> RUSTFMT
|
PR_TRIGGER --> RUSTFMT
|
||||||
RUSTFMT --> CLIPPY
|
RUSTFMT --> CLIPPY
|
||||||
@ -724,15 +725,17 @@ graph TB
|
|||||||
CARGO_TEST --> TSC
|
CARGO_TEST --> TSC
|
||||||
TSC --> VITEST
|
TSC --> VITEST
|
||||||
|
|
||||||
MASTER_TRIGGER --> AMD64
|
MAIN_TRIGGER --> AMD64
|
||||||
MASTER_TRIGGER --> WINDOWS
|
MAIN_TRIGGER --> WINDOWS
|
||||||
MASTER_TRIGGER --> ARM64
|
MAIN_TRIGGER --> ARM64
|
||||||
MASTER_TRIGGER --> MACOS
|
MAIN_TRIGGER --> MACOS_ARM
|
||||||
|
MAIN_TRIGGER --> MACOS_INTEL
|
||||||
|
|
||||||
AMD64 --> RELEASE
|
AMD64 --> RELEASE
|
||||||
WINDOWS --> RELEASE
|
WINDOWS --> RELEASE
|
||||||
ARM64 --> RELEASE
|
ARM64 --> RELEASE
|
||||||
MACOS --> RELEASE
|
MACOS_ARM --> RELEASE
|
||||||
|
MACOS_INTEL --> RELEASE
|
||||||
|
|
||||||
DOCKER_TRIGGER --> REGISTRY
|
DOCKER_TRIGGER --> REGISTRY
|
||||||
|
|
||||||
|
|||||||
@ -4,67 +4,39 @@
|
|||||||
|
|
||||||
| Component | URL | Notes |
|
| Component | URL | Notes |
|
||||||
|-----------|-----|-------|
|
|-----------|-----|-------|
|
||||||
| Gitea | `https://gogs.tftsr.com` / `http://172.0.0.29:3000` | Git server (migrated from Gogs 0.14) |
|
| GitHub | `https://github.com/msicie/apollo_nxt-trcaa` | Git server and CI/CD platform |
|
||||||
| Woodpecker CI (direct) | `http://172.0.0.29:8084` | v2.x |
|
| GitHub Actions | Native to GitHub | Hosted runners (`ubuntu-latest`, `macos-latest`, `macos-13`) |
|
||||||
| Woodpecker CI (proxy) | `http://172.0.0.29:8085` | nginx reverse proxy |
|
| ghcr.io | `ghcr.io/msicie/` | GitHub Container Registry for pre-baked CI images |
|
||||||
| PostgreSQL (Gitea DB) | Container: `gogs_postgres_db` | DB: `gogsdb`, User: `gogs` |
|
|
||||||
|
|
||||||
### CI Agents
|
|
||||||
|
|
||||||
| Agent | Platform | Host | Purpose |
|
|
||||||
|-------|----------|------|---------|
|
|
||||||
| `gitea_act_runner_amd64` (Docker) | `linux-amd64` | 172.0.0.29 | Native x86_64 — test builds + amd64/windows release |
|
|
||||||
| `act_runner` (systemd) | `linux-arm64` | 172.0.0.29 | Native aarch64 — arm64 release builds |
|
|
||||||
| `act_runner` (launchd) | `macos-arm64` | sarman's local Mac | Native Apple Silicon — macOS `.dmg` release builds |
|
|
||||||
|
|
||||||
Agent labels configured in `~/.config/act_runner/config.yaml`:
|
|
||||||
```yaml
|
|
||||||
runner:
|
|
||||||
labels:
|
|
||||||
- "macos-arm64:host"
|
|
||||||
```
|
|
||||||
macOS runner runs jobs **directly on the host** (no Docker container) — macOS SDK cannot run in Docker.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Pre-baked Builder Images
|
## Pre-baked Builder Images
|
||||||
|
|
||||||
CI build and test jobs use pre-baked Docker images pushed to the local Gitea registry
|
CI build and test jobs use pre-baked Docker images pushed to `ghcr.io/msicie/`. These images bake in all system dependencies (Tauri libs, Node.js, Rust toolchain, cross-compilers) so that CI jobs skip package installation entirely.
|
||||||
at `172.0.0.29:3000`. These images bake in all system dependencies (Tauri libs, Node.js,
|
|
||||||
Rust toolchain, cross-compilers) so that CI jobs skip package installation entirely.
|
|
||||||
|
|
||||||
| Image | Used by jobs | Contents |
|
| Image | Used by jobs | Contents |
|
||||||
|-------|-------------|----------|
|
|-------|-------------|----------|
|
||||||
| `172.0.0.29:3000/sarman/trcaa-linux-amd64:rust1.88-node22` | `rust-fmt-check`, `rust-clippy`, `rust-tests`, `build-linux-amd64` | Rust 1.88 + rustfmt + clippy + Tauri amd64 libs + Node.js 22 |
|
| `ghcr.io/msicie/trcaa-linux-amd64:rust1.88-node22` | `rust-test`, `build-linux-amd64` | Rust 1.88 + rustfmt + clippy + Tauri amd64 libs + Node.js 22 |
|
||||||
| `172.0.0.29:3000/sarman/trcaa-windows-cross:rust1.88-node22` | `build-windows-amd64` | Rust 1.88 + mingw-w64 + NSIS + Node.js 22 |
|
| `ghcr.io/msicie/trcaa-windows-cross:rust1.88-node22` | `build-windows-amd64` | Rust 1.88 + mingw-w64 + NSIS + Node.js 22 |
|
||||||
| `172.0.0.29:3000/sarman/trcaa-linux-arm64:rust1.88-node22` | `build-linux-arm64` | Rust 1.88 + aarch64 cross-toolchain + arm64 multiarch libs + Node.js 22 |
|
| `ghcr.io/msicie/trcaa-linux-arm64:rust1.88-node22` | `build-linux-arm64` | Rust 1.88 + aarch64 cross-toolchain + arm64 multiarch libs + Node.js 22 |
|
||||||
|
|
||||||
**Rebuild triggers:** Rust toolchain version bump, webkit2gtk/gtk major version change, Node.js major version change.
|
**Rebuild triggers:** Rust toolchain version bump, webkit2gtk/gtk major version change, Node.js major version change.
|
||||||
|
|
||||||
**How to rebuild images:**
|
**How to rebuild images:**
|
||||||
1. Trigger `build-images.yml` via `workflow_dispatch` in the Gitea Actions UI
|
1. Trigger `build-images.yml` via Actions → Build CI Docker Images → Run workflow
|
||||||
2. Confirm all 3 images appear in the Gitea package/container registry at `172.0.0.29:3000`
|
2. Confirm all 3 images appear in `ghcr.io/msicie/`
|
||||||
3. Only then merge workflow changes that depend on the new image contents
|
3. Only then merge workflow changes that depend on the new image contents
|
||||||
|
|
||||||
**Server prerequisite — insecure registry** (one-time, on 172.0.0.29):
|
|
||||||
```sh
|
|
||||||
echo '{"insecure-registries":["172.0.0.29:3000"]}' | sudo tee /etc/docker/daemon.json
|
|
||||||
sudo systemctl restart docker
|
|
||||||
```
|
|
||||||
This must be configured on every machine running an act_runner for the runner's Docker
|
|
||||||
daemon to pull from the local HTTP registry.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Cargo and npm Caching
|
## Cargo and npm Caching
|
||||||
|
|
||||||
All Rust and build jobs use `actions/cache@v3` to cache downloaded package artifacts.
|
All Rust and build jobs use `actions/cache@v4` to cache downloaded package artifacts.
|
||||||
Gitea 1.22 implements the GitHub Actions cache API natively.
|
|
||||||
|
|
||||||
**Cargo cache** (Rust jobs):
|
**Cargo cache** (Rust jobs):
|
||||||
```yaml
|
```yaml
|
||||||
- name: Cache cargo registry
|
- name: Cache cargo registry
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cargo/registry/index
|
~/.cargo/registry/index
|
||||||
@ -78,7 +50,7 @@ Gitea 1.22 implements the GitHub Actions cache API natively.
|
|||||||
**npm cache** (frontend and build jobs):
|
**npm cache** (frontend and build jobs):
|
||||||
```yaml
|
```yaml
|
||||||
- name: Cache npm
|
- name: Cache npm
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ~/.npm
|
path: ~/.npm
|
||||||
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
|
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
|
||||||
@ -92,168 +64,108 @@ Cache keys for cross-compile jobs use a suffix to avoid collisions:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Test Pipeline (`.gitea/workflows/test.yml`)
|
## Test Pipeline (`.github/workflows/test.yml`)
|
||||||
|
|
||||||
**Triggers:** Pull requests only.
|
**Triggers:** Every push to `main`, `feature/**`, `bug/**`, `fix/**` branches; pull requests targeting `main`.
|
||||||
|
|
||||||
```
|
```
|
||||||
Pipeline jobs (run in parallel):
|
Jobs (run in parallel):
|
||||||
1. rust-fmt-check → cargo fmt --check
|
rust-test → cargo fmt --check
|
||||||
2. rust-clippy → cargo clippy -- -D warnings
|
→ cargo clippy -- -D warnings
|
||||||
3. rust-tests → cargo test (64 tests)
|
→ cargo test (64 tests)
|
||||||
4. frontend-typecheck → npx tsc --noEmit
|
frontend-test → npx tsc --noEmit
|
||||||
5. frontend-tests → npm run test:run (13 Vitest tests)
|
→ npm run test:run (Vitest tests)
|
||||||
```
|
```
|
||||||
|
|
||||||
**Docker images used:**
|
**Docker image used:**
|
||||||
- `172.0.0.29:3000/sarman/trcaa-linux-amd64:rust1.88-node22` — Rust steps (replaces `rust:1.88-slim`)
|
- `ghcr.io/msicie/trcaa-linux-amd64:rust1.88-node22` — both Rust and frontend steps
|
||||||
- `node:22-alpine` — Frontend steps
|
|
||||||
|
Job names `rust-test` and `frontend-test` must match exactly — these are the required status check names in branch protection on `main`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Release Pipeline (`.gitea/workflows/auto-tag.yml`)
|
## Release Pipeline (`.github/workflows/release.yml`)
|
||||||
|
|
||||||
**Triggers:** Pushes to `master` (auto-tag), then release build/upload jobs run after `autotag`.
|
**Triggers:** Push to `main` (auto-tag job), then release build/upload jobs run after `autotag` completes on `v*` tags.
|
||||||
|
|
||||||
Auto tags are created by `.gitea/workflows/auto-tag.yml` using `git tag` + `git push`.
|
Auto-tags are created by the `autotag` job using `git tag` + `git push`. Release jobs depend on `autotag` and run in parallel.
|
||||||
Release jobs are executed in the same workflow and depend on `autotag` completion.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
Jobs (run in parallel after autotag):
|
Jobs (run in parallel after autotag):
|
||||||
build-linux-amd64 → image: trcaa-linux-amd64:rust1.88-node22
|
build-linux-amd64 → image: ghcr.io/msicie/trcaa-linux-amd64:rust1.88-node22
|
||||||
→ cargo tauri build (x86_64-unknown-linux-gnu)
|
→ cargo tauri build (x86_64-unknown-linux-gnu)
|
||||||
→ {.deb, .rpm, .AppImage} uploaded to Gitea release
|
→ {.deb, .rpm, .AppImage} uploaded to GitHub Release
|
||||||
→ fails fast if no Linux artifacts are produced
|
→ fails fast if no Linux artifacts are produced
|
||||||
build-windows-amd64 → image: trcaa-windows-cross:rust1.88-node22
|
|
||||||
|
build-windows-amd64 → image: ghcr.io/msicie/trcaa-windows-cross:rust1.88-node22
|
||||||
→ cargo tauri build (x86_64-pc-windows-gnu) via mingw-w64
|
→ cargo tauri build (x86_64-pc-windows-gnu) via mingw-w64
|
||||||
→ {.exe, .msi} uploaded to Gitea release
|
→ {.exe, .msi} uploaded to GitHub Release
|
||||||
→ fails fast if no Windows artifacts are produced
|
→ fails fast if no Windows artifacts are produced
|
||||||
build-linux-arm64 → image: trcaa-linux-arm64:rust1.88-node22 (ubuntu:22.04-based)
|
|
||||||
|
build-linux-arm64 → image: ghcr.io/msicie/trcaa-linux-arm64:rust1.88-node22
|
||||||
→ cargo tauri build (aarch64-unknown-linux-gnu)
|
→ cargo tauri build (aarch64-unknown-linux-gnu)
|
||||||
→ {.deb, .rpm, .AppImage} uploaded to Gitea release
|
→ {.deb, .rpm, .AppImage} uploaded to GitHub Release
|
||||||
→ fails fast if no Linux artifacts are produced
|
→ fails fast if no Linux artifacts are produced
|
||||||
build-macos-arm64 → cargo tauri build (aarch64-apple-darwin) — runs on local Mac
|
|
||||||
→ {.dmg} uploaded to Gitea release
|
build-macos-arm64 → runs-on: macos-latest (Apple Silicon)
|
||||||
|
→ cargo tauri build (aarch64-apple-darwin) natively
|
||||||
|
→ {.dmg} uploaded to GitHub Release
|
||||||
→ existing same-name assets are deleted before upload (rerun-safe)
|
→ existing same-name assets are deleted before upload (rerun-safe)
|
||||||
→ unsigned; after install run: xattr -cr /Applications/TFTSR.app
|
→ unsigned; after install run: xattr -cr /Applications/TRCAA.app
|
||||||
```
|
|
||||||
|
|
||||||
**Per-step agent routing (Woodpecker 2.x labels):**
|
build-macos-intel → runs-on: macos-13 (Intel x86_64)
|
||||||
|
→ cargo tauri build (x86_64-apple-darwin) natively
|
||||||
```yaml
|
→ {.dmg} uploaded to GitHub Release
|
||||||
steps:
|
|
||||||
- name: build-linux-amd64
|
|
||||||
labels:
|
|
||||||
platform: linux/amd64 # → woodpecker_agent on 172.0.0.29
|
|
||||||
|
|
||||||
- name: build-linux-arm64
|
|
||||||
labels:
|
|
||||||
platform: linux/arm64 # → woodpecker-agent.service on local arm64 machine
|
|
||||||
```
|
|
||||||
|
|
||||||
**Multi-agent workspace isolation:**
|
|
||||||
|
|
||||||
Steps routed to different agents do **not** share a workspace. The arm64 step clones
|
|
||||||
the repo directly within its commands (using `http://172.0.0.29:3000`, accessible from
|
|
||||||
the local machine) and uploads its artifacts inline. The `upload-release` step (amd64)
|
|
||||||
handles amd64 + windows artifacts only.
|
|
||||||
|
|
||||||
**Clone override (auto-tag.yml — amd64 workspace):**
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
clone:
|
|
||||||
git:
|
|
||||||
image: alpine/git
|
|
||||||
network_mode: gogs_default
|
|
||||||
commands:
|
|
||||||
- git init -b master
|
|
||||||
- git remote add origin http://gitea_app:3000/sarman/tftsr-devops_investigation.git
|
|
||||||
- git fetch --depth=1 origin +refs/tags/${CI_COMMIT_TAG}:refs/tags/${CI_COMMIT_TAG}
|
|
||||||
- git checkout ${CI_COMMIT_TAG}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Windows cross-compile environment:**
|
**Windows cross-compile environment:**
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
env:
|
||||||
TARGET: x86_64-pc-windows-gnu
|
TARGET: x86_64-pc-windows-gnu
|
||||||
CC_x86_64_pc_windows_gnu: x86_64-w64-mingw32-gcc
|
CC_x86_64_pc_windows_gnu: x86_64-w64-mingw32-gcc
|
||||||
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: x86_64-w64-mingw32-gcc
|
CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: x86_64-w64-mingw32-gcc
|
||||||
|
OPENSSL_NO_VENDOR: "0"
|
||||||
|
OPENSSL_STATIC: "1"
|
||||||
```
|
```
|
||||||
|
|
||||||
**Artifacts per platform:**
|
**Artifacts per platform:**
|
||||||
- Linux amd64: `.deb`, `.rpm`, `.AppImage`
|
- Linux amd64: `.deb`, `.rpm`, `.AppImage`
|
||||||
- Windows amd64: `.exe` (NSIS installer), `.msi`
|
- Windows amd64: `.exe` (NSIS installer), `.msi`
|
||||||
- Linux arm64: `.deb`, `.rpm`, `.AppImage`
|
- Linux arm64: `.deb`, `.rpm`, `.AppImage`
|
||||||
|
- macOS ARM64: `.dmg`
|
||||||
**Upload step (requires gogs_default network for amd64, host IP for arm64):**
|
- macOS Intel: `.dmg`
|
||||||
```yaml
|
|
||||||
# amd64 upload step
|
|
||||||
upload-release:
|
|
||||||
image: curlimages/curl:latest
|
|
||||||
labels:
|
|
||||||
platform: linux/amd64
|
|
||||||
network_mode: gogs_default
|
|
||||||
secrets: [GOGS_TOKEN]
|
|
||||||
```
|
|
||||||
|
|
||||||
The `GOGS_TOKEN` Woodpecker secret must be created via the Woodpecker UI or API after
|
|
||||||
migration. The secret name stays `GOGS_TOKEN` for pipeline compatibility.
|
|
||||||
|
|
||||||
**Gitea Release API (replaces Gogs API — same endpoints, different container name):**
|
|
||||||
```bash
|
|
||||||
# Create release
|
|
||||||
POST http://gitea_app:3000/api/v1/repos/sarman/tftsr-devops_investigation/releases
|
|
||||||
Authorization: token $GOGS_TOKEN
|
|
||||||
|
|
||||||
# Upload artifact
|
|
||||||
POST http://gitea_app:3000/api/v1/repos/sarman/tftsr-devops_investigation/releases/{id}/assets
|
|
||||||
```
|
|
||||||
|
|
||||||
From the arm64 agent (local machine), use `http://172.0.0.29:3000/api/v1` instead.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Multi-File Pipeline Support (Woodpecker 2.x)
|
## Build Images Workflow (`.github/workflows/build-images.yml`)
|
||||||
|
|
||||||
Woodpecker 2.x supports multiple pipeline files in the `.woodpecker/` directory.
|
**Triggers:** Changes to `.docker/**` on `main`; manual `workflow_dispatch`.
|
||||||
All `.yml` files are evaluated on every trigger; `when:` conditions control which
|
|
||||||
pipelines actually run.
|
|
||||||
|
|
||||||
Current files:
|
Builds and pushes all three pre-baked CI images to `ghcr.io/msicie/`:
|
||||||
- `.woodpecker/test.yml` — runs on every push/PR
|
```
|
||||||
- `.woodpecker/release.yml` — runs on `v*` tags only
|
Jobs (all run on ubuntu-latest):
|
||||||
|
build-linux-amd64-image → .docker/Dockerfile.linux-amd64
|
||||||
|
→ ghcr.io/msicie/trcaa-linux-amd64:rust1.88-node22
|
||||||
|
|
||||||
No DB config path switching needed (unlike Woodpecker 0.15.4).
|
build-windows-cross-image → .docker/Dockerfile.windows-cross
|
||||||
|
→ ghcr.io/msicie/trcaa-windows-cross:rust1.88-node22
|
||||||
|
|
||||||
---
|
build-linux-arm64-image → .docker/Dockerfile.linux-arm64
|
||||||
|
→ ghcr.io/msicie/trcaa-linux-arm64:rust1.88-node22
|
||||||
|
```
|
||||||
|
|
||||||
## Webhook Configuration
|
Authentication: `docker login ghcr.io -u ${{ github.actor }} --password-stdin <<< "${{ secrets.GITHUB_TOKEN }}"`. Requires `packages: write` permission.
|
||||||
|
|
||||||
**Woodpecker 2.x with Gitea OAuth2:**
|
|
||||||
|
|
||||||
After migration, Woodpecker 2.x registers webhooks automatically when a repo is
|
|
||||||
activated via the UI. No manual JWT-signed webhook setup required.
|
|
||||||
|
|
||||||
1. Log in at `http://172.0.0.29:8085` via Gitea OAuth2
|
|
||||||
2. Add repo `sarman/tftsr-devops_investigation`
|
|
||||||
3. Woodpecker creates webhook in Gitea automatically
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Branch Protection
|
## Branch Protection
|
||||||
|
|
||||||
Master branch is protected: all changes require a PR.
|
`main` branch requires:
|
||||||
|
- All changes via PR
|
||||||
```sql
|
- 1 approving review
|
||||||
-- Gitea branch protection (via psql on gogs_postgres_db container)
|
- CODEOWNER review (`@Shaun-Arman-VFK387_moto` and `@github-copilot`)
|
||||||
-- Check protection
|
- Required status checks: `rust-test`, `frontend-test`
|
||||||
SELECT name, protected, require_pull_request FROM protect_branch WHERE repo_id=42;
|
- `enforce_admins: false` — owner and admins can bypass with `gh pr merge --admin`
|
||||||
|
|
||||||
-- Temporarily disable for urgent fixes (restore immediately after!)
|
|
||||||
UPDATE protect_branch SET protected=false WHERE repo_id=42 AND name='master';
|
|
||||||
-- ... push ...
|
|
||||||
UPDATE protect_branch SET protected=true, require_pull_request=true WHERE repo_id=42 AND name='master';
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -264,7 +176,7 @@ Configuration lives in `cliff.toml` at the repo root.
|
|||||||
|
|
||||||
### How it works
|
### How it works
|
||||||
|
|
||||||
A `changelog` job in `auto-tag.yml` runs in parallel with the build jobs, immediately
|
A `changelog` job in `release.yml` runs in parallel with the build jobs, immediately
|
||||||
after `autotag` completes:
|
after `autotag` completes:
|
||||||
|
|
||||||
1. Clones the full repo history with all tags (`--depth=2147483647` — git-cliff needs
|
1. Clones the full repo history with all tags (`--depth=2147483647` — git-cliff needs
|
||||||
@ -272,9 +184,9 @@ after `autotag` completes:
|
|||||||
2. Downloads the git-cliff v2.7.0 static musl binary (~5 MB, no image change needed).
|
2. Downloads the git-cliff v2.7.0 static musl binary (~5 MB, no image change needed).
|
||||||
3. Runs `git-cliff --output CHANGELOG.md` to regenerate the full cumulative changelog.
|
3. Runs `git-cliff --output CHANGELOG.md` to regenerate the full cumulative changelog.
|
||||||
4. Runs `git-cliff --latest --strip all` to produce release notes for the new tag only.
|
4. Runs `git-cliff --latest --strip all` to produce release notes for the new tag only.
|
||||||
5. PATCHes the Gitea release body with those notes (replaces the static `"Release vX.Y.Z"`).
|
5. Updates the GitHub Release body with those notes via `gh release edit`.
|
||||||
6. Commits `CHANGELOG.md` to master with `[skip ci]` appended to the message.
|
6. Commits `CHANGELOG.md` to `main` with `[skip ci]` appended to the message.
|
||||||
The `[skip ci]` token prevents `auto-tag.yml` from re-triggering on the CHANGELOG commit.
|
The `[skip ci]` token prevents `release.yml` from re-triggering on the CHANGELOG commit.
|
||||||
7. Uploads `CHANGELOG.md` as a release asset (replaces any previous version).
|
7. Uploads `CHANGELOG.md` as a release asset (replaces any previous version).
|
||||||
|
|
||||||
### cliff.toml reference
|
### cliff.toml reference
|
||||||
@ -289,17 +201,9 @@ after `autotag` completes:
|
|||||||
|
|
||||||
### Loop prevention
|
### Loop prevention
|
||||||
|
|
||||||
The `[skip ci]` suffix on the CHANGELOG commit message is recognised by Gitea Actions
|
The `[skip ci]` suffix on the CHANGELOG commit message is recognised by GitHub Actions
|
||||||
and causes the workflow to be skipped for that push. Without it, the CHANGELOG commit
|
and causes the workflow to be skipped for that push. Without it, the CHANGELOG commit
|
||||||
would trigger `auto-tag.yml` again, incrementing the patch version forever.
|
would trigger `release.yml` again, incrementing the patch version forever.
|
||||||
|
|
||||||
### Bootstrap
|
|
||||||
|
|
||||||
The initial `CHANGELOG.md` was generated locally before the first PR:
|
|
||||||
```sh
|
|
||||||
git-cliff --config cliff.toml --output CHANGELOG.md
|
|
||||||
```
|
|
||||||
Subsequent runs are fully automated by CI.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -312,27 +216,16 @@ index is duplicated and certain `-dev` package pairs cannot be co-installed beca
|
|||||||
don't declare `Multi-Arch: same`. This produces `E: Unable to correct problems, you have
|
don't declare `Multi-Arch: same`. This produces `E: Unable to correct problems, you have
|
||||||
held broken packages` and cannot be fixed by tweaking `sources.list` entries.
|
held broken packages` and cannot be fixed by tweaking `sources.list` entries.
|
||||||
|
|
||||||
**Fix**: Use `ubuntu:22.04` as the container image. Ubuntu routes arm64 through
|
**Fix**: Use `ubuntu:22.04` as the container image (see `Dockerfile.linux-arm64`). Ubuntu
|
||||||
`ports.ubuntu.com/ubuntu-ports` — a separate mirror from `archive.ubuntu.com` (amd64).
|
routes arm64 through `ports.ubuntu.com/ubuntu-ports` — a separate mirror from
|
||||||
There are no cross-arch index overlaps and the dependency resolver succeeds. Rust must be
|
`archive.ubuntu.com` (amd64). There are no cross-arch index overlaps and the dependency
|
||||||
installed manually via `rustup` since it is not pre-installed in the Ubuntu base image.
|
resolver succeeds. Rust must be installed manually via `rustup`.
|
||||||
|
|
||||||
### Step Containers Cannot Reach `gitea_app`
|
### `CI=true` Required by Tauri CLI
|
||||||
Default Docker bridge containers cannot resolve `gitea_app` or reach `172.0.0.29:3000`
|
GitHub Actions sets `CI=true` by default — `cargo tauri build` accepts this without
|
||||||
(host firewall). Fix: use `network_mode: gogs_default` in any step that needs Gitea
|
modification. Prefix the command explicitly if your runner environment is unusual:
|
||||||
access. Requires `repo_trusted=1`.
|
```yaml
|
||||||
|
- run: CI=true cargo tauri build --target $TARGET
|
||||||
### `CI=woodpecker` Rejected by Tauri CLI
|
|
||||||
Woodpecker sets `CI=woodpecker`; `cargo tauri build` expects a boolean. Fix: prefix with
|
|
||||||
`CI=true cargo tauri build`.
|
|
||||||
|
|
||||||
### Agent Stalls After Server Restart
|
|
||||||
After restarting the Woodpecker server, the agent may enter a loop cleaning up orphaned
|
|
||||||
containers and stop picking up new builds. Fix:
|
|
||||||
```bash
|
|
||||||
docker rm -f $(docker ps -aq --filter 'name=0_')
|
|
||||||
docker volume rm $(docker volume ls -q | grep '0_')
|
|
||||||
docker restart woodpecker_agent
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Windows DLL Export Ordinal Too Large
|
### Windows DLL Export Ordinal Too Large
|
||||||
@ -344,32 +237,17 @@ Fix: `src-tauri/.cargo/config.toml`:
|
|||||||
rustflags = ["-C", "link-arg=-Wl,--exclude-all-symbols"]
|
rustflags = ["-C", "link-arg=-Wl,--exclude-all-symbols"]
|
||||||
```
|
```
|
||||||
|
|
||||||
### GOGS_TOKEN Secret Must Be Recreated After Migration
|
### Release Artifacts Not Uploaded
|
||||||
After migrating from Woodpecker 0.15.4 to 2.x, recreate the `GOGS_TOKEN` secret:
|
|
||||||
1. Log in to Gitea, create a new API token under Settings → Applications
|
|
||||||
2. In Woodpecker UI → Repository → Secrets, add secret `GOGS_TOKEN` with the token value
|
|
||||||
|
|
||||||
---
|
**Cause:** `GITHUB_TOKEN` needs `contents: write` permission in the workflow.
|
||||||
|
|
||||||
## Gitea PostgreSQL Access
|
Verify the `release.yml` permissions block includes:
|
||||||
|
```yaml
|
||||||
```bash
|
permissions:
|
||||||
docker exec gogs_postgres_db psql -U gogs -d gogsdb -c "SELECT id, lower_name FROM repository;"
|
contents: write
|
||||||
```
|
```
|
||||||
|
|
||||||
> Database name is `gogsdb` (unchanged from Gogs migration).
|
### Runner Group Restrictions (Enterprise)
|
||||||
|
GitHub Enterprise organizations may restrict which repositories can use GitHub-hosted
|
||||||
---
|
runners. If jobs are stuck in queue, contact your org admin to add the repository to the
|
||||||
|
allowed runner group, or temporarily make the repo public for the bootstrap run.
|
||||||
## Migration Notes (Gogs 0.14 → Gitea)
|
|
||||||
|
|
||||||
Gitea auto-migrates the Gogs PostgreSQL schema on first start. Users, repos, teams, and
|
|
||||||
issues are preserved. API tokens stored in the DB are also migrated but should be
|
|
||||||
regenerated for security.
|
|
||||||
|
|
||||||
Key changes after migration:
|
|
||||||
- Container name: `gogs_app` → `gitea_app`
|
|
||||||
- Config dir: `/data/gitea` (was `/data/gogs` inside container, same host volume)
|
|
||||||
- Repo dir: `gogs-repositories` → `gitea-repositories` (renamed on host during migration)
|
|
||||||
- OAuth2 provider: Gitea now supports OAuth2 (Woodpecker 2.x uses this for login)
|
|
||||||
- Woodpecker 2.x multi-file pipeline support enabled (no more single config file limitation)
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
**Troubleshooting and RCA Assistant** is a secure desktop application for guided IT incident triage, root cause analysis (RCA), and post-mortem documentation. Built with Tauri 2.x (Rust + WebView) and React 18.
|
**Troubleshooting and RCA Assistant** is a secure desktop application for guided IT incident triage, root cause analysis (RCA), and post-mortem documentation. Built with Tauri 2.x (Rust + WebView) and React 18.
|
||||||
|
|
||||||
**CI:**  — rustfmt · clippy · 64 Rust tests · tsc · vitest — all green
|
**CI:**  — rustfmt · clippy · 64 Rust tests · tsc · vitest — all green
|
||||||
|
|
||||||
## Quick Navigation
|
## Quick Navigation
|
||||||
|
|
||||||
@ -15,7 +15,7 @@
|
|||||||
| [LiteLLM + Bedrock Setup](wiki/LiteLLM-Bedrock-Setup) | AWS Bedrock integration via LiteLLM proxy |
|
| [LiteLLM + Bedrock Setup](wiki/LiteLLM-Bedrock-Setup) | AWS Bedrock integration via LiteLLM proxy |
|
||||||
| [PII Detection](wiki/PII-Detection) | Patterns, redaction flow, security |
|
| [PII Detection](wiki/PII-Detection) | Patterns, redaction flow, security |
|
||||||
| [IPC Commands](wiki/IPC-Commands) | Full list of Tauri backend commands |
|
| [IPC Commands](wiki/IPC-Commands) | Full list of Tauri backend commands |
|
||||||
| [CI/CD Pipeline](wiki/CICD-Pipeline) | Gitea Actions setup, multi-platform builds, act_runner config |
|
| [CI/CD Pipeline](wiki/CICD-Pipeline) | GitHub Actions setup, multi-platform builds, pre-baked ghcr.io images |
|
||||||
| [Security Model](wiki/Security-Model) | Encryption, audit trail, capabilities |
|
| [Security Model](wiki/Security-Model) | Encryption, audit trail, capabilities |
|
||||||
| [Integrations](wiki/Integrations) | Confluence, ServiceNow, Azure DevOps (v0.2) |
|
| [Integrations](wiki/Integrations) | Confluence, ServiceNow, Azure DevOps (v0.2) |
|
||||||
| [Troubleshooting](wiki/Troubleshooting) | Known issues and fixes |
|
| [Troubleshooting](wiki/Troubleshooting) | Known issues and fixes |
|
||||||
@ -45,7 +45,7 @@
|
|||||||
|
|
||||||
**Platforms:** linux/amd64 · linux/arm64 · windows/amd64 (.deb, .rpm, .AppImage, .exe, .msi)
|
**Platforms:** linux/amd64 · linux/arm64 · windows/amd64 (.deb, .rpm, .AppImage, .exe, .msi)
|
||||||
|
|
||||||
Download from [Releases](https://gogs.tftsr.com/sarman/tftsr-devops_investigation/releases). All builds are produced natively (no QEMU emulation).
|
Download from [Releases](https://github.com/msicie/apollo_nxt-trcaa/releases). All builds are produced natively (no QEMU emulation).
|
||||||
|
|
||||||
## Project Status
|
## Project Status
|
||||||
|
|
||||||
@ -54,8 +54,8 @@ Download from [Releases](https://gogs.tftsr.com/sarman/tftsr-devops_investigatio
|
|||||||
| Phases 1–8 (Core application) | ✅ Complete |
|
| Phases 1–8 (Core application) | ✅ Complete |
|
||||||
| Phase 9 (History/Search) | 🔲 Pending |
|
| Phase 9 (History/Search) | 🔲 Pending |
|
||||||
| Phase 10 (Integrations) | ✅ Complete — Confluence, ServiceNow, Azure DevOps fully implemented with OAuth2 |
|
| Phase 10 (Integrations) | ✅ Complete — Confluence, ServiceNow, Azure DevOps fully implemented with OAuth2 |
|
||||||
| Phase 11 (CI/CD) | ✅ Complete — Gitea Actions fully operational |
|
| Phase 11 (CI/CD) | ✅ Complete — GitHub Actions fully operational |
|
||||||
| Phase 12 (Release packaging) | ✅ linux/amd64 · linux/arm64 (native) · windows/amd64 |
|
| Phase 12 (Release packaging) | ✅ linux/amd64 · linux/arm64 · windows/amd64 · macOS ARM64 · macOS Intel |
|
||||||
|
|
||||||
## Tech Stack
|
## Tech Stack
|
||||||
|
|
||||||
@ -69,4 +69,4 @@ Download from [Releases](https://gogs.tftsr.com/sarman/tftsr-devops_investigatio
|
|||||||
| Secret storage | tauri-plugin-stronghold |
|
| Secret storage | tauri-plugin-stronghold |
|
||||||
| State | Zustand |
|
| State | Zustand |
|
||||||
| Testing | Vitest (13 frontend) + `#[cfg(test)]` (64 Rust tests) |
|
| Testing | Vitest (13 frontend) + `#[cfg(test)]` (64 Rust tests) |
|
||||||
| CI/CD | Gitea Actions (act_runner v0.3.1) + Gitea |
|
| CI/CD | GitHub Actions + ghcr.io |
|
||||||
|
|||||||
@ -1,71 +1,41 @@
|
|||||||
# Troubleshooting
|
# Troubleshooting
|
||||||
|
|
||||||
## CI/CD — Gitea Actions
|
## CI/CD — GitHub Actions
|
||||||
|
|
||||||
### Build Not Triggering After Push
|
### Build Not Triggering After Push
|
||||||
|
|
||||||
**Check:**
|
**Check:**
|
||||||
1. Verify the workflow file exists in `.gitea/workflows/` on the pushed branch
|
1. Verify the workflow file exists in `.github/workflows/` on the pushed branch
|
||||||
2. Check the Actions tab at `http://172.0.0.29:3000/sarman/tftsr-devops_investigation/actions`
|
2. Check the Actions tab at `https://github.com/msicie/apollo_nxt-trcaa/actions`
|
||||||
3. Confirm the act_runner is online: `docker logs gitea_act_runner_amd64 --since 5m`
|
3. Confirm the workflow trigger matches the branch (e.g., `push: branches: [main, 'bug/**']`)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Job Container Can't Reach Gitea (`172.0.0.29:3000` blocked)
|
### Jobs Stuck in Queue
|
||||||
|
|
||||||
**Cause:** act_runner creates an isolated Docker network per job (when `container:` is specified). Traffic from the job container to `172.0.0.29:3000` is blocked by the host firewall.
|
**Cause:** GitHub Enterprise organizations may restrict which repositories can use
|
||||||
|
GitHub-hosted runners via runner group policies.
|
||||||
|
|
||||||
**Fix:** Ensure `container.network: host` is set in the act_runner config AND that `CONFIG_FILE=/data/config.yaml` is in the container's environment:
|
**Fix:** Contact your org admin to add the repository to the allowed runner group, or
|
||||||
|
temporarily make the repo public for a one-time bootstrap run (e.g., to build the
|
||||||
```yaml
|
initial ghcr.io images).
|
||||||
# /docker_mounts/gitea/runner/amd64/config.yaml
|
|
||||||
container:
|
|
||||||
network: "host"
|
|
||||||
```
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# docker-compose.yml for act-runner-amd64
|
|
||||||
environment:
|
|
||||||
- CONFIG_FILE=/data/config.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
Also set `capacity: 1` — with capacity > 1, concurrent jobs may not get host networking:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
runner:
|
|
||||||
capacity: 1
|
|
||||||
```
|
|
||||||
|
|
||||||
Restart runner: `docker restart gitea_act_runner_amd64`
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `Unable to locate package git` in Rust Job
|
### `manifest unknown` — Image Pull Fails
|
||||||
|
|
||||||
**Cause:** `rust:1.88-slim` has an empty apt package cache.
|
**Cause:** The pre-baked CI image (`ghcr.io/msicie/trcaa-linux-amd64:rust1.88-node22`)
|
||||||
|
doesn't exist yet. This happens before the first `build-images.yml` run.
|
||||||
|
|
||||||
**Fix:** Always run `apt-get update` before `apt-get install`:
|
**Fix:**
|
||||||
```yaml
|
1. Go to Actions → Build CI Docker Images → Run workflow
|
||||||
- name: Checkout
|
2. Wait for all 3 image builds to complete
|
||||||
run: |
|
3. Confirm images appear at `https://github.com/orgs/msicie/packages`
|
||||||
apt-get update -qq && apt-get install -y -qq git
|
4. Re-run the failing workflow
|
||||||
git init
|
|
||||||
git remote add origin http://172.0.0.29:3000/sarman/tftsr-devops_investigation.git
|
|
||||||
git fetch --depth=1 origin $GITHUB_SHA
|
|
||||||
git checkout FETCH_HEAD
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `exec: "node": executable file not found in $PATH`
|
### Job Skipped on Tag Push
|
||||||
|
|
||||||
**Cause:** `actions/checkout@v4` is a Node.js action. `rust:1.88-slim` and similar slim images don't have Node.
|
|
||||||
|
|
||||||
**Fix:** Don't use `actions/checkout@v4` — use direct git commands instead (see above).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Job Skipped (status 6) on Tag Push
|
|
||||||
|
|
||||||
**Cause:** Pattern matching issue with `on: push: tags:`. Use unquoted glob in the workflow:
|
**Cause:** Pattern matching issue with `on: push: tags:`. Use unquoted glob in the workflow:
|
||||||
|
|
||||||
@ -92,29 +62,17 @@ on:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `CI=woodpecker` Rejected by `cargo tauri build`
|
|
||||||
|
|
||||||
**Cause:** CI runners set `CI=woodpecker` (string). Tauri CLI expects `true`/`false`.
|
|
||||||
|
|
||||||
**Fix:** Prefix the build command:
|
|
||||||
```yaml
|
|
||||||
- run: CI=true cargo tauri build --target $TARGET
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Release Artifacts Not Uploaded
|
### Release Artifacts Not Uploaded
|
||||||
|
|
||||||
**Cause 1:** `RELEASE_TOKEN` secret not set or expired.
|
**Cause:** `GITHUB_TOKEN` permissions insufficient. The `release.yml` workflow requires
|
||||||
```bash
|
`contents: write` to create releases and upload assets.
|
||||||
# Recreate via admin CLI:
|
|
||||||
docker exec -u git gitea_app gitea admin user generate-access-token \
|
|
||||||
--username sarman --token-name gitea-ci-token --raw \
|
|
||||||
--scopes 'write:repository,read:user'
|
|
||||||
# Add the token as RELEASE_TOKEN in repo Settings > Actions > Secrets
|
|
||||||
```
|
|
||||||
|
|
||||||
**Cause 2:** Each build job uploads its own artifacts independently. All jobs require host network on the runner (see above).
|
Verify the permissions block:
|
||||||
|
```yaml
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -158,7 +116,7 @@ Auto-fix: `cargo clippy --manifest-path src-tauri/Cargo.toml --fix --allow-dirty
|
|||||||
**Fix (Fedora/RHEL):**
|
**Fix (Fedora/RHEL):**
|
||||||
```bash
|
```bash
|
||||||
sudo dnf install -y glib2-devel gtk3-devel webkit2gtk4.1-devel \
|
sudo dnf install -y glib2-devel gtk3-devel webkit2gtk4.1-devel \
|
||||||
libsoup3-devel openssl-devel librsvg2-devel
|
libsoup3-devel openssl-devel librsvg2-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
**Fix (Debian/Ubuntu):**
|
**Fix (Debian/Ubuntu):**
|
||||||
@ -169,6 +127,17 @@ sudo apt-get install -y libwebkit2gtk-4.1-dev libssl-dev libgtk-3-dev \
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Windows Cross-Compile: DLL Export Ordinal Too Large
|
||||||
|
`/usr/bin/x86_64-w64-mingw32-ld: error: export ordinal too large: 106290`
|
||||||
|
|
||||||
|
Fix: `src-tauri/.cargo/config.toml`:
|
||||||
|
```toml
|
||||||
|
[target.x86_64-pc-windows-gnu]
|
||||||
|
rustflags = ["-C", "link-arg=-Wl,--exclude-all-symbols"]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Database
|
## Database
|
||||||
|
|
||||||
### DB Won't Open in Production
|
### DB Won't Open in Production
|
||||||
@ -220,27 +189,3 @@ const title = detail.title;
|
|||||||
Common causes:
|
Common causes:
|
||||||
- Mocked `invoke()` return type doesn't match updated command signature
|
- Mocked `invoke()` return type doesn't match updated command signature
|
||||||
- `sessionStore` state not reset between tests (call `store.reset()` in `beforeEach`)
|
- `sessionStore` state not reset between tests (call `store.reset()` in `beforeEach`)
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Gitea
|
|
||||||
|
|
||||||
### API Token Authentication
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -H "Authorization: token <token_value>" http://172.0.0.29:3000/api/v1/user
|
|
||||||
```
|
|
||||||
|
|
||||||
Create tokens in Gitea Settings > Applications > Access Tokens, or via admin CLI:
|
|
||||||
```bash
|
|
||||||
docker exec -u git gitea_app gitea admin user generate-access-token \
|
|
||||||
--username sarman --token-name mytoken --raw --scopes 'read:user,write:repository'
|
|
||||||
```
|
|
||||||
|
|
||||||
### PostgreSQL Access
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker exec gogs_postgres_db psql -U gogs -d gogsdb -c "SELECT id, lower_name, is_private FROM repository;"
|
|
||||||
```
|
|
||||||
|
|
||||||
Database is named `gogsdb`. The PostgreSQL instance uses SCRAM-SHA-256 auth (MD5 also configured for the `gogs` user for compatibility with older clients).
|
|
||||||
|
|||||||
@ -4,11 +4,11 @@ import path from "node:path";
|
|||||||
|
|
||||||
const autoTagWorkflowPath = path.resolve(
|
const autoTagWorkflowPath = path.resolve(
|
||||||
process.cwd(),
|
process.cwd(),
|
||||||
".gitea/workflows/auto-tag.yml",
|
".github/workflows/release.yml",
|
||||||
);
|
);
|
||||||
|
|
||||||
describe("auto-tag workflow release triggering", () => {
|
describe("auto-tag workflow release triggering", () => {
|
||||||
it("creates tags via git push instead of Gitea tag API", () => {
|
it("creates tags via git push instead of API call", () => {
|
||||||
const workflow = readFileSync(autoTagWorkflowPath, "utf-8");
|
const workflow = readFileSync(autoTagWorkflowPath, "utf-8");
|
||||||
|
|
||||||
expect(workflow).toContain("git push origin \"refs/tags/$NEXT\"");
|
expect(workflow).toContain("git push origin \"refs/tags/$NEXT\"");
|
||||||
@ -23,7 +23,13 @@ describe("auto-tag workflow release triggering", () => {
|
|||||||
expect(workflow).toContain("build-macos-arm64:");
|
expect(workflow).toContain("build-macos-arm64:");
|
||||||
expect(workflow).toContain("build-linux-arm64:");
|
expect(workflow).toContain("build-linux-arm64:");
|
||||||
expect(workflow).toContain("needs: autotag");
|
expect(workflow).toContain("needs: autotag");
|
||||||
expect(workflow).toContain("TAG=$(curl -s \"$API/tags?limit=50\"");
|
expect(workflow).toContain("git tag --sort=-version:refname");
|
||||||
expect(workflow).toContain("ERROR: Could not resolve release tag from repository tags.");
|
});
|
||||||
|
|
||||||
|
it("also includes macOS Intel build job", () => {
|
||||||
|
const workflow = readFileSync(autoTagWorkflowPath, "utf-8");
|
||||||
|
|
||||||
|
expect(workflow).toContain("build-macos-intel:");
|
||||||
|
expect(workflow).toContain("macos-13");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -100,10 +100,10 @@ describe("Dockerfile.linux-arm64", () => {
|
|||||||
// ─── build-images.yml workflow ───────────────────────────────────────────────
|
// ─── build-images.yml workflow ───────────────────────────────────────────────
|
||||||
|
|
||||||
describe("build-images.yml workflow", () => {
|
describe("build-images.yml workflow", () => {
|
||||||
const wf = readFile(".gitea/workflows/build-images.yml");
|
const wf = readFile(".github/workflows/build-images.yml");
|
||||||
|
|
||||||
it("triggers on changes to .docker/ files on master", () => {
|
it("triggers on changes to .docker/ files on main", () => {
|
||||||
expect(wf).toContain("- master");
|
expect(wf).toContain("- main");
|
||||||
expect(wf).toContain("- '.docker/**'");
|
expect(wf).toContain("- '.docker/**'");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -111,38 +111,28 @@ describe("build-images.yml workflow", () => {
|
|||||||
expect(wf).toContain("workflow_dispatch:");
|
expect(wf).toContain("workflow_dispatch:");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not explicitly mount the Docker socket (act_runner mounts it automatically)", () => {
|
it("authenticates to ghcr.io before pushing", () => {
|
||||||
// act_runner already mounts /var/run/docker.sock; an explicit options: mount
|
expect(wf).toContain("docker login ghcr.io");
|
||||||
// causes a 'Duplicate mount point' error and must not be present.
|
|
||||||
expect(wf).not.toContain("-v /var/run/docker.sock:/var/run/docker.sock");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("authenticates to the local Gitea registry before pushing", () => {
|
|
||||||
expect(wf).toContain("docker login");
|
|
||||||
expect(wf).toContain("--password-stdin");
|
expect(wf).toContain("--password-stdin");
|
||||||
expect(wf).toContain("172.0.0.29:3000");
|
expect(wf).toContain("ghcr.io");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("builds and pushes all three platform images", () => {
|
it("builds and pushes all three platform images to ghcr.io", () => {
|
||||||
expect(wf).toContain("trcaa-linux-amd64:rust1.88-node22");
|
expect(wf).toContain("ghcr.io/msicie/trcaa-linux-amd64:rust1.88-node22");
|
||||||
expect(wf).toContain("trcaa-windows-cross:rust1.88-node22");
|
expect(wf).toContain("ghcr.io/msicie/trcaa-windows-cross:rust1.88-node22");
|
||||||
expect(wf).toContain("trcaa-linux-arm64:rust1.88-node22");
|
expect(wf).toContain("ghcr.io/msicie/trcaa-linux-arm64:rust1.88-node22");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("uses alpine:latest with docker-cli (not docker:24-cli which triggers duplicate socket mount in act_runner)", () => {
|
it("runs all three build jobs on ubuntu-latest runner", () => {
|
||||||
// act_runner v0.3.1 special-cases docker:* images and adds the socket bind;
|
const matches = wf.match(/runs-on: ubuntu-latest/g) ?? [];
|
||||||
// combined with its global socket bind this causes a 'Duplicate mount point' error.
|
|
||||||
expect(wf).toContain("alpine:latest");
|
|
||||||
expect(wf).toContain("docker-cli");
|
|
||||||
expect(wf).not.toContain("docker:24-cli");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("runs all three build jobs on linux-amd64 runner", () => {
|
|
||||||
const matches = wf.match(/runs-on: linux-amd64/g) ?? [];
|
|
||||||
expect(matches.length).toBeGreaterThanOrEqual(3);
|
expect(matches.length).toBeGreaterThanOrEqual(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("uses RELEASE_TOKEN secret for registry auth", () => {
|
it("uses GITHUB_TOKEN for registry auth", () => {
|
||||||
expect(wf).toContain("secrets.RELEASE_TOKEN");
|
expect(wf).toContain("secrets.GITHUB_TOKEN");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("grants packages write permission", () => {
|
||||||
|
expect(wf).toContain("packages: write");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import path from "node:path";
|
|||||||
|
|
||||||
const autoTagWorkflowPath = path.resolve(
|
const autoTagWorkflowPath = path.resolve(
|
||||||
process.cwd(),
|
process.cwd(),
|
||||||
".gitea/workflows/auto-tag.yml",
|
".github/workflows/release.yml",
|
||||||
);
|
);
|
||||||
|
|
||||||
describe("auto-tag release macOS bundle path", () => {
|
describe("auto-tag release macOS bundle path", () => {
|
||||||
|
|||||||
52
ticket-727547-summary.md
Normal file
52
ticket-727547-summary.md
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# Ticket Summary — ADO #727547
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Migrate the `tftsr-devops_investigation` repository from `gogs.tftsr.com/sarman/tftsr-devops_investigation` to `github.com/msicie/apollo_nxt-trcaa`. All CI/CD pipelines, container registries, and PR review tooling must be rebuilt from scratch targeting GitHub. The self-hosted qwen3-coder-next LLM reviewer is replaced by native GitHub Copilot code review. Branch protection on `main` must require passing CI checks and allow owner/CODEOWNERS to bypass.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- [x] Repository exists at `github.com/msicie/apollo_nxt-trcaa` with `main` as the default branch
|
||||||
|
- [x] `.github/workflows/test.yml` runs Rust and frontend tests on every push/PR targeting `main`
|
||||||
|
- [x] `.github/workflows/release.yml` auto-tags, builds for Linux amd64+arm64, Windows amd64, macOS ARM64+Intel, and uploads artifacts to GitHub Releases
|
||||||
|
- [x] `.github/workflows/build-images.yml` builds and pushes pre-baked CI images to `ghcr.io/msicie/`
|
||||||
|
- [x] All Gogs/Gitea pipeline references (`.gitea/workflows/`, `172.0.0.29:3000`, `RELEASE_TOKEN`) removed
|
||||||
|
- [x] PR review uses native GitHub Copilot (no external LLM service required)
|
||||||
|
- [x] `.github/CODEOWNERS` requires `@Shaun-Arman-VFK387_moto` and `@github-copilot` on all PRs
|
||||||
|
- [x] `main` branch protection: requires `rust-test`, `frontend-test`, CODEOWNER review; admins can bypass
|
||||||
|
- [x] Wiki sync targets `github.com/msicie/apollo_nxt-trcaa/wiki`
|
||||||
|
- [ ] One-time: trigger `build-images.yml` to bootstrap `ghcr.io/msicie/` images
|
||||||
|
- [ ] One-time: enable Copilot Code Review in `msicie` org settings
|
||||||
|
|
||||||
|
## Work Implemented
|
||||||
|
|
||||||
|
| File | Change |
|
||||||
|
|---|---|
|
||||||
|
| `.github/workflows/test.yml` | Full rewrite — port from `.gitea/workflows/test.yml` (Gitea); jobs renamed to `rust-test` + `frontend-test` to match branch protection check names; uses `ghcr.io/msicie/trcaa-linux-amd64:rust1.88-node22` |
|
||||||
|
| `.github/workflows/release.yml` | Full rewrite — port from `.gitea/workflows/auto-tag.yml`; GITHUB_TOKEN replaces RELEASE_TOKEN; all Gogs API calls replaced with `gh` CLI; adds `build-macos-intel` job (`macos-13`); `master` refs → `main` |
|
||||||
|
| `.github/workflows/build-images.yml` | Rewrite — login to `ghcr.io` with GITHUB_TOKEN; push images to `ghcr.io/msicie/trcaa-*` |
|
||||||
|
| `.github/workflows/pr-review.yml` | **Deleted** — replaced by native GitHub Copilot |
|
||||||
|
| `.gitea/workflows/` | **Deleted** entire directory |
|
||||||
|
| `.github/CODEOWNERS` | **Created** — `@Shaun-Arman-VFK387_moto @github-copilot` on all paths |
|
||||||
|
| `Makefile` | Replace `GOGS_API`/`GOGS_REPO`/`GOGS_TOKEN` with `GH_REPO`/`GH_TOKEN` and `gh release upload` |
|
||||||
|
| `CLAUDE.md` | Update wiki URL, CI/CD section, branch references (`master` → `main`) |
|
||||||
|
|
||||||
|
**Branch protection on `main`:**
|
||||||
|
- Require PRs before merging
|
||||||
|
- Require 1 approving review
|
||||||
|
- Require CODEOWNER review (`require_code_owner_reviews: true`)
|
||||||
|
- Required status checks: `rust-test`, `frontend-test`
|
||||||
|
- `enforce_admins: false` — owner and admins can bypass
|
||||||
|
|
||||||
|
**PR:** https://github.com/msicie/apollo_nxt-trcaa/pull/1
|
||||||
|
|
||||||
|
## Testing Needed
|
||||||
|
|
||||||
|
1. **Bootstrap Docker images** (one-time): Go to Actions → Build CI Docker Images → Run workflow. Verify all three images appear at `ghcr.io/msicie/`.
|
||||||
|
2. **Enable Copilot Code Review** (one-time manual): `msicie` org Settings → Copilot → Code Review → Enable.
|
||||||
|
3. **Test pipeline**: Verify `rust-test` and `frontend-test` checks appear and pass on PR #1.
|
||||||
|
4. **Copilot review**: After enabling, open a new PR and confirm `@github-copilot` is auto-requested.
|
||||||
|
5. **Branch protection enforcement**: Attempt to merge a PR with a failing check — confirm it is blocked.
|
||||||
|
6. **Owner bypass**: Confirm `@Shaun-Arman-VFK387_moto` can override protection and merge.
|
||||||
|
7. **Release pipeline**: Push a `v*` tag (e.g. `v0.3.10`) and confirm all 5 platform jobs complete and artifacts appear in GitHub Releases.
|
||||||
|
8. **Wiki sync**: Confirm release workflow wiki-sync job pushes content to `github.com/msicie/apollo_nxt-trcaa/wiki`.
|
||||||
@ -16,17 +16,17 @@ Conventional Commits throughout but the information was never surfaced to end-us
|
|||||||
- `cliff.toml` (new) — git-cliff configuration; defines commit parsers, ignored tags,
|
- `cliff.toml` (new) — git-cliff configuration; defines commit parsers, ignored tags,
|
||||||
output template, and which commit types appear in the changelog
|
output template, and which commit types appear in the changelog
|
||||||
- `CHANGELOG.md` (new) — bootstrapped from all existing tags; maintained by CI going forward
|
- `CHANGELOG.md` (new) — bootstrapped from all existing tags; maintained by CI going forward
|
||||||
- `.gitea/workflows/auto-tag.yml` — new `changelog` job that runs after `autotag`
|
- `.github/workflows/release.yml` — `changelog` job that runs after `autotag`
|
||||||
- `docs/wiki/CICD-Pipeline.md` — "Changelog Generation" section added
|
- `docs/wiki/CICD-Pipeline.md` — "Changelog Generation" section added
|
||||||
|
|
||||||
## Acceptance Criteria
|
## Acceptance Criteria
|
||||||
|
|
||||||
- [ ] `cliff.toml` present at repo root with working Tera template
|
- [ ] `cliff.toml` present at repo root with working Tera template
|
||||||
- [ ] `CHANGELOG.md` present at repo root, bootstrapped from all existing semver tags
|
- [ ] `CHANGELOG.md` present at repo root, bootstrapped from all existing semver tags
|
||||||
- [ ] `changelog` job in `auto-tag.yml` runs after `autotag` (parallel with build jobs)
|
- [ ] `changelog` job in `release.yml` runs after `autotag` (parallel with build jobs)
|
||||||
- [ ] Each Gitea release body shows grouped conventional-commit entries instead of
|
- [ ] Each GitHub Release body shows grouped conventional-commit entries instead of
|
||||||
static `"Release vX.Y.Z"`
|
static `"Release vX.Y.Z"`
|
||||||
- [ ] `CHANGELOG.md` committed to master on every release with `[skip ci]` suffix
|
- [ ] `CHANGELOG.md` committed to `main` on every release with `[skip ci]` suffix
|
||||||
(no infinite re-trigger loop)
|
(no infinite re-trigger loop)
|
||||||
- [ ] `CHANGELOG.md` uploaded as a downloadable release asset
|
- [ ] `CHANGELOG.md` uploaded as a downloadable release asset
|
||||||
- [ ] CI/chore/build/test/style commits excluded from changelog output
|
- [ ] CI/chore/build/test/style commits excluded from changelog output
|
||||||
@ -47,15 +47,15 @@ Conventional Commits throughout but the information was never surfaced to end-us
|
|||||||
- Covers all tagged versions from `v0.1.0` through `v0.2.49` plus `[Unreleased]`
|
- Covers all tagged versions from `v0.1.0` through `v0.2.49` plus `[Unreleased]`
|
||||||
- 267 lines covering the full project history
|
- 267 lines covering the full project history
|
||||||
|
|
||||||
### `.gitea/workflows/auto-tag.yml` — `changelog` job
|
### `.github/workflows/release.yml` — `changelog` job
|
||||||
- `needs: autotag` — waits for the new tag to exist before running
|
- `needs: autotag` — waits for the new tag to exist before running
|
||||||
- Full history clone: `git fetch --tags --depth=2147483647` so git-cliff can resolve
|
- Full history clone: `git fetch --tags --depth=2147483647` so git-cliff can resolve
|
||||||
all version boundaries
|
all version boundaries
|
||||||
- git-cliff v2.7.0 downloaded as a static x86_64 musl binary (~5 MB); no custom
|
- git-cliff v2.7.0 downloaded as a static x86_64 musl binary (~5 MB); no custom
|
||||||
image required
|
image required
|
||||||
- Generates full `CHANGELOG.md` and per-release notes (`--latest --strip all`)
|
- Generates full `CHANGELOG.md` and per-release notes (`--latest --strip all`)
|
||||||
- PATCHes the Gitea release body via API with JSON-safe escaping (`jq -Rs .`)
|
- Updates the GitHub Release body via `gh release edit` with JSON-safe escaping (`jq -Rs .`)
|
||||||
- Commits `CHANGELOG.md` to master with `[skip ci]` to prevent workflow re-trigger
|
- Commits `CHANGELOG.md` to `main` with `[skip ci]` to prevent workflow re-trigger
|
||||||
- Deletes any existing `CHANGELOG.md` asset before re-uploading (rerun-safe)
|
- Deletes any existing `CHANGELOG.md` asset before re-uploading (rerun-safe)
|
||||||
- Runs in parallel with all build jobs — no added wall-clock latency
|
- Runs in parallel with all build jobs — no added wall-clock latency
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ on each job invocation: `apt-get update`, Tauri system libs, Node.js via nodesou
|
|||||||
the arm64 job — a full `rustup` install. This was the primary cause of slow builds.
|
the arm64 job — a full `rustup` install. This was the primary cause of slow builds.
|
||||||
|
|
||||||
The repository already contains pre-baked builder Docker images (`.docker/Dockerfile.*`) and a
|
The repository already contains pre-baked builder Docker images (`.docker/Dockerfile.*`) and a
|
||||||
`build-images.yml` workflow to push them to the local Gitea registry at `172.0.0.29:3000`.
|
`build-images.yml` workflow to push them to `ghcr.io/msicie/`.
|
||||||
These images were never referenced by the actual CI jobs — a critical gap. This work closes
|
These images were never referenced by the actual CI jobs — a critical gap. This work closes
|
||||||
that gap and adds `actions/cache@v3` for Cargo and npm.
|
that gap and adds `actions/cache@v3` for Cargo and npm.
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ that gap and adds `actions/cache@v3` for Cargo and npm.
|
|||||||
|
|
||||||
- [ ] `Dockerfile.linux-amd64` includes `rustfmt` and `clippy` components
|
- [ ] `Dockerfile.linux-amd64` includes `rustfmt` and `clippy` components
|
||||||
- [ ] `Dockerfile.linux-arm64` includes `rustfmt` and `clippy` components
|
- [ ] `Dockerfile.linux-arm64` includes `rustfmt` and `clippy` components
|
||||||
- [ ] `test.yml` Rust jobs use `172.0.0.29:3000/sarman/trcaa-linux-amd64:rust1.88-node22`
|
- [ ] `test.yml` Rust jobs use `ghcr.io/msicie/trcaa-linux-amd64:rust1.88-node22`
|
||||||
- [ ] `test.yml` Rust jobs have no inline `apt-get` or `rustup component add` steps
|
- [ ] `test.yml` Rust jobs have no inline `apt-get` or `rustup component add` steps
|
||||||
- [ ] `test.yml` Rust jobs include `actions/cache@v3` for `~/.cargo/registry`
|
- [ ] `test.yml` Rust jobs include `actions/cache@v3` for `~/.cargo/registry`
|
||||||
- [ ] `test.yml` frontend jobs include `actions/cache@v3` for `~/.npm`
|
- [ ] `test.yml` frontend jobs include `actions/cache@v3` for `~/.npm`
|
||||||
@ -38,9 +38,9 @@ in the image rather than installing them at job runtime.
|
|||||||
Added `&& /root/.cargo/bin/rustup component add rustfmt clippy` appended to the
|
Added `&& /root/.cargo/bin/rustup component add rustfmt clippy` appended to the
|
||||||
existing `rustup` installation RUN command (chained with `&&` to keep it one layer).
|
existing `rustup` installation RUN command (chained with `&&` to keep it one layer).
|
||||||
|
|
||||||
### `.gitea/workflows/test.yml`
|
### `.github/workflows/test.yml`
|
||||||
- **rust-fmt-check**, **rust-clippy**, **rust-tests**: switched container image from
|
- **rust-test** (fmt + clippy + tests): switched container image from
|
||||||
`rust:1.88-slim` → `172.0.0.29:3000/sarman/trcaa-linux-amd64:rust1.88-node22`.
|
`rust:1.88-slim` → `ghcr.io/msicie/trcaa-linux-amd64:rust1.88-node22`.
|
||||||
Removed `apt-get install git` from Checkout steps (git is pre-installed in image).
|
Removed `apt-get install git` from Checkout steps (git is pre-installed in image).
|
||||||
Removed `apt-get install libwebkit2gtk-...` steps.
|
Removed `apt-get install libwebkit2gtk-...` steps.
|
||||||
Removed `rustup component add rustfmt` and `rustup component add clippy` steps.
|
Removed `rustup component add rustfmt` and `rustup component add clippy` steps.
|
||||||
@ -49,15 +49,15 @@ existing `rustup` installation RUN command (chained with `&&` to keep it one lay
|
|||||||
- **frontend-typecheck**, **frontend-tests**: kept `node:22-alpine` image (no change needed).
|
- **frontend-typecheck**, **frontend-tests**: kept `node:22-alpine` image (no change needed).
|
||||||
Added `actions/cache@v3` step for `~/.npm` keyed on `package-lock.json` hash.
|
Added `actions/cache@v3` step for `~/.npm` keyed on `package-lock.json` hash.
|
||||||
|
|
||||||
### `.gitea/workflows/auto-tag.yml`
|
### `.github/workflows/release.yml`
|
||||||
- **build-linux-amd64**: image `rust:1.88-slim` → `trcaa-linux-amd64:rust1.88-node22`.
|
- **build-linux-amd64**: image `rust:1.88-slim` → `ghcr.io/msicie/trcaa-linux-amd64:rust1.88-node22`.
|
||||||
Removed Checkout apt-get install git, removed entire Install dependencies step.
|
Removed Checkout apt-get install git, removed entire Install dependencies step.
|
||||||
Removed `rustup target add x86_64-unknown-linux-gnu` from Build step. Added cargo + npm cache.
|
Removed `rustup target add x86_64-unknown-linux-gnu` from Build step. Added cargo + npm cache.
|
||||||
- **build-windows-amd64**: image `rust:1.88-slim` → `trcaa-windows-cross:rust1.88-node22`.
|
- **build-windows-amd64**: image `rust:1.88-slim` → `ghcr.io/msicie/trcaa-windows-cross:rust1.88-node22`.
|
||||||
Removed Checkout apt-get install git, removed entire Install dependencies step.
|
Removed Checkout apt-get install git, removed entire Install dependencies step.
|
||||||
Removed `rustup target add x86_64-pc-windows-gnu` from Build step.
|
Removed `rustup target add x86_64-pc-windows-gnu` from Build step.
|
||||||
Added cargo (with `-windows-` suffix key to avoid collision) + npm cache.
|
Added cargo (with `-windows-` suffix key to avoid collision) + npm cache.
|
||||||
- **build-linux-arm64**: image `ubuntu:22.04` → `trcaa-linux-arm64:rust1.88-node22`.
|
- **build-linux-arm64**: image `ubuntu:22.04` → `ghcr.io/msicie/trcaa-linux-arm64:rust1.88-node22`.
|
||||||
Removed Checkout apt-get install git, removed entire Install dependencies step (~40 lines).
|
Removed Checkout apt-get install git, removed entire Install dependencies step (~40 lines).
|
||||||
Removed `. "$HOME/.cargo/env"` (PATH already set via `ENV` in Dockerfile).
|
Removed `. "$HOME/.cargo/env"` (PATH already set via `ENV` in Dockerfile).
|
||||||
Removed `rustup target add aarch64-unknown-linux-gnu` from Build step.
|
Removed `rustup target add aarch64-unknown-linux-gnu` from Build step.
|
||||||
@ -67,7 +67,7 @@ existing `rustup` installation RUN command (chained with `&&` to keep it one lay
|
|||||||
Added two new sections before the Test Pipeline section:
|
Added two new sections before the Test Pipeline section:
|
||||||
- **Pre-baked Builder Images**: table of all three images and their contents, rebuild
|
- **Pre-baked Builder Images**: table of all three images and their contents, rebuild
|
||||||
triggers, how-to-rebuild instructions, and the insecure-registries Docker daemon
|
triggers, how-to-rebuild instructions, and the insecure-registries Docker daemon
|
||||||
prerequisite for 172.0.0.29.
|
prerequisite for ghcr.io access.
|
||||||
- **Cargo and npm Caching**: documents the `actions/cache@v3` key patterns in use,
|
- **Cargo and npm Caching**: documents the `actions/cache@v3` key patterns in use,
|
||||||
including the per-platform cache key suffixes for cross-compile jobs.
|
including the per-platform cache key suffixes for cross-compile jobs.
|
||||||
Updated the Test Pipeline section to reference the correct pre-baked image name.
|
Updated the Test Pipeline section to reference the correct pre-baked image name.
|
||||||
@ -75,21 +75,16 @@ Updated the Release Pipeline job table to show which image each build job uses.
|
|||||||
|
|
||||||
## Testing Needed
|
## Testing Needed
|
||||||
|
|
||||||
1. **Pre-build images** (prerequisite): Trigger `build-images.yml` via `workflow_dispatch`
|
1. **Pre-build images** (prerequisite): Trigger `build-images.yml` via Actions → Build CI Docker Images → Run workflow. Confirm all 3 images are pushed and visible at `ghcr.io/msicie/`.
|
||||||
on Gitea Actions UI. Confirm all 3 images are pushed and visible in the registry.
|
|
||||||
|
|
||||||
2. **Server prerequisite**: Confirm `/etc/docker/daemon.json` on `172.0.0.29` contains
|
2. **PR test suite**: Open a PR with these changes. Verify:
|
||||||
`{"insecure-registries":["172.0.0.29:3000"]}` and Docker was restarted after.
|
- `rust-test` and `frontend-test` jobs pass
|
||||||
|
|
||||||
3. **PR test suite**: Open a PR with these changes. Verify:
|
|
||||||
- All 5 test jobs pass (`rust-fmt-check`, `rust-clippy`, `rust-tests`,
|
|
||||||
`frontend-typecheck`, `frontend-tests`)
|
|
||||||
- Job logs show no `apt-get` or `rustup component add` output
|
- Job logs show no `apt-get` or `rustup component add` output
|
||||||
- Cache hit messages appear on second run
|
- Cache hit messages appear on second run
|
||||||
|
|
||||||
4. **Release build**: Merge to master. Verify `auto-tag.yml` runs and:
|
3. **Release build**: Merge to `main`. Verify `release.yml` runs and:
|
||||||
- All 3 Linux/Windows build jobs start without Install dependencies step
|
- All build jobs start without Install dependencies step
|
||||||
- Artifacts are produced and uploaded to the Gitea release
|
- Artifacts are produced and uploaded to the GitHub Release
|
||||||
- Total release time is significantly reduced (~7 min vs ~25 min before)
|
- Total release time is significantly reduced (~7 min vs ~25 min before)
|
||||||
|
|
||||||
5. **Expected time savings after caching warms up**:
|
5. **Expected time savings after caching warms up**:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user