Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## Команды

**Taskfile.yaml — источник правды.** Смотри `task --list` для актуального списка команд.
**Taskfile.yaml — источник правды.** Смотри `task --list-all` для актуального списка команд и классов побочных эффектов.

Основные:
- `task up` — полный setup (init + bootstrap + app-of-apps)
Expand All @@ -16,7 +16,12 @@
Sealed Secrets:
- `task seal:openrouter` — создать SealedSecret для OpenRouter API
- `task seal:github` — создать SealedSecret для GitHub репо
- `task seal:postgree` — создать SealedSecret для PostgreSQL
- `task seal:postgres` — создать SealedSecret для PostgreSQL
- `task seal:postgree` — legacy-команда, сохраняющая имя Secret `chat-postgree`

`seal:*` — опциональные операторские утилиты, они не вызываются активными
dev/smoke workflow. Значения читаются из переменных окружения и не передаются в
аргументах процесса. Старый формат `KEY=value` намеренно отклоняется.

## Переменные окружения

Expand All @@ -27,6 +32,9 @@ Sealed Secrets:
- `GITHUB_PAT` / `GITHUB_USERNAME` / `GITHUB_REPO_URL` — для ArgoCD Image Updater
- `CLOUDFLARE_TOKEN` — токен Cloudflare API для cert-manager и external-dns

`task app-of-apps` по умолчанию использует `app-poly-gitops-k8s@v1.5.0`.
Переопределение `GITOPS_REVISION` принимает только release tag или полный SHA.

## Структура

```
Expand Down
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ TF_VAR_node_count=1
# TF_VAR_max_cost_rub=80

# === Application Secrets ===
# Optional operator inputs for `task seal:*`. These are not consumed by the
# active dev/smoke roots unless the rendered SealedSecret is reviewed and added
# to the GitOps repository. Values are read from the environment, never argv.
# OpenRouter API
OPENROUTER_API_KEY=sk-or-xxx

Expand All @@ -30,5 +33,5 @@ GITHUB_PAT=github_pat_xxx
GITHUB_USERNAME=justgithubaccount
GITHUB_REPO_URL=https://github.com/justgithubaccount/app-poly-gitops-helm

# PostgreSQL (when ready)
# PostgreSQL (optional; retained for future external database integration)
# DATABASE_URL=postgresql://user:pass@host:5432/db
16 changes: 10 additions & 6 deletions .github/workflows/application-live-smoke.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ jobs:
(github.event_name == 'push' && contains(github.event.head_commit.message, '[live-smoke]'))
runs-on: ubuntu-latest
timeout-minutes: 20
env:
CHAT_BACKEND_REVISION: 6686997d9c4e8d6815886790341d5e185f86bf1a
CREWAI_REVISION: 0835d3102555e6cef4fb700c56969ecddc6f6ddd
UI_REVISION: 06575c95fe30eadc85b3441df26792eef8631683
steps:
- name: Checkout smoke harness
uses: actions/checkout@v7
Expand All @@ -38,28 +42,28 @@ jobs:
uses: actions/checkout@v7
with:
repository: justgithubaccount/app-poly-gitops-fastapi
ref: v1.1.2
ref: ${{ env.CHAT_BACKEND_REVISION }}
path: sources/fastapi
persist-credentials: false
- name: Checkout CrewAI release
uses: actions/checkout@v7
with:
repository: justgithubaccount/app-poly-gitops-crewai
ref: v0.1.3
ref: ${{ env.CREWAI_REVISION }}
path: sources/crewai
persist-credentials: false
- name: Checkout reviewed UI implementation
uses: actions/checkout@v7
with:
repository: justgithubaccount/app-poly-gitops-ui
ref: feat/crewai-automation
ref: ${{ env.UI_REVISION }}
path: sources/ui
persist-credentials: false
- name: Verify audited source revisions before exposing the key
run: |
test "$(git -C sources/fastapi rev-parse HEAD)" = 6686997d9c4e8d6815886790341d5e185f86bf1a
test "$(git -C sources/crewai rev-parse HEAD)" = 0835d3102555e6cef4fb700c56969ecddc6f6ddd
test "$(git -C sources/ui rev-parse HEAD)" = 2852b17530f7eac756c3e4b6a3e35b1ef8f7837b
test "$(git -C sources/fastapi rev-parse HEAD)" = "${CHAT_BACKEND_REVISION}"
test "$(git -C sources/crewai rev-parse HEAD)" = "${CREWAI_REVISION}"
test "$(git -C sources/ui rev-parse HEAD)" = "${UI_REVISION}"
- uses: astral-sh/setup-uv@v10.3.2
with:
enable-cache: true
Expand Down
31 changes: 19 additions & 12 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,31 @@ jobs:
- uses: actions/checkout@v4

- name: Install Task
uses: arduino/setup-task@v2
uses: arduino/setup-task@b91d5d2c96a56797b48ac1e0e89220bf64044611
with:
version: 3.x
version: 3.54.0

- name: Validate Taskfile
run: task --list
run: task --list-all --json > /dev/null

- name: Install offline test dependencies
run: |
python3 -m venv .venv-ci
.venv-ci/bin/pip install PyYAML==6.0.2

- name: Test Taskfile and live-smoke contracts
run: .venv-ci/bin/python -m unittest discover -s tests -p 'test_*.py' -v

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd
with:
terraform_version: "1.6"
terraform_version: "1.13.5"

- name: Terraform Format Check
run: terraform fmt -check -recursive terraform/

- name: Terraform Init (no backend)
run: terraform -chdir=terraform/timeweb init -backend=false
run: terraform -chdir=terraform/timeweb init -backend=false -input=false

- name: Terraform Validate
run: terraform -chdir=terraform/timeweb validate
Expand All @@ -49,20 +57,18 @@ jobs:
document-start: disable

- name: Check shell scripts
uses: ludeeus/action-shellcheck@master
uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38
with:
scandir: './scripts'
severity: warning
version: v0.11.0

- name: Test disposable GitOps workflow
run: bash tests/test_ephemeral_smoke.sh

- name: Test Timeweb floating IP cleanup workflow
run: bash tests/test_timeweb_floating_ip_cleanup.sh

- name: Test live application smoke budget guard (offline)
run: python3 -m unittest discover -s tests -p test_application_live_smoke.py -v

security:
name: Security Scan
runs-on: ubuntu-latest
Expand All @@ -78,8 +84,9 @@ jobs:
GITLEAKS_ENABLE_COMMENTS: false

- name: tfsec
uses: aquasecurity/tfsec-action@v1.0.3
uses: aquasecurity/tfsec-action@b466648d6e39e7c75324f25d83891162a721f2d6
with:
working_directory: terraform/timeweb
soft_fail: true
version: v1.28.14
soft_fail: false
github_token: ${{ secrets.GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ kubeconfig*
.env
secrets/
*secret*
!scripts/render-secret-json.py

# IDE
.idea/
Expand Down
28 changes: 24 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ when debugging is complete.

## Local provisioning

Requirements: Terraform 1.6+, Task, kubectl, Helm 3, and a Timeweb API token.
Requirements: Terraform 1.13.5, Task 3.54.0, kubectl, Helm 3, curl, jq, and a
Timeweb API token. Python 3 and kubeseal are additionally required only for the
optional SealedSecret helper.

~~~bash
cp .env.example .env
Expand All @@ -53,6 +55,12 @@ task up
`~/.kube/timeweb-config`, installs Argo CD, and applies the root application.
Review the plan, selected presets, and cost estimate first.

Task descriptions begin with a side-effect class: `[read-only]`,
`[local-write]`, `[mutating]`, `[destructive]`, or `[secret-sensitive]`. Use
`task --list-all` to review the full interface before execution. The default
GitOps root is `app-poly-gitops-k8s@v1.5.0`; an operator may supply another
release tag or full commit SHA with `GITOPS_REVISION=...`.

Useful read and cleanup commands:

~~~bash
Expand Down Expand Up @@ -82,6 +90,14 @@ persistent environment, copy `terraform/timeweb/backend.s3.tf.example` to a
Argo CD chart values are in `bootstrap/argocd/values.yaml`. The smoke root is
`bootstrap/argocd/gitops-smoke-root.yaml`.

The `seal:*` tasks are optional manifest-rendering utilities and are not called
by active dev/smoke workflows. They read secret values from named environment
variables and write the rendered SealedSecret to stdout. The corrected
`seal:postgres` name is canonical; `seal:postgree` remains a compatibility
entrypoint that preserves the existing `chat-postgree` Secret name consumed by
the GitOps repository. Legacy `KEY=value` command arguments are rejected because
they expose secret values through process listings.

## Repository structure

- `terraform/timeweb/` — Timeweb provider, preset selection, cost guard, and module call
Expand All @@ -96,13 +112,16 @@ Argo CD chart values are in `bootstrap/argocd/values.yaml`. The smoke root is
Offline repository checks:

~~~bash
task --list
task --list-all --json > /dev/null
python3 -m venv .venv-ci
.venv-ci/bin/pip install PyYAML==6.0.2
.venv-ci/bin/python -m unittest discover -s tests -p 'test_*.py' -v
terraform fmt -check -recursive terraform
terraform -chdir=terraform/timeweb init -backend=false
terraform -chdir=terraform/timeweb init -backend=false -input=false
terraform -chdir=terraform/timeweb validate
bash tests/test_ephemeral_smoke.sh
bash tests/test_timeweb_floating_ip_cleanup.sh
python3 -m unittest discover -s tests -p test_application_live_smoke.py -v
tfsec terraform/timeweb
~~~

Do not run `task up`, Terraform apply/destroy, or the Timeweb workflows as a
Expand All @@ -111,6 +130,7 @@ documentation check.
## Documentation

- [Architecture](docs/ARCHITECTURE.md)
- [Taskfile and operator contracts](docs/TASKFILE.md)
- [Tenant applications](docs/TENANT-APPS.md)

## Related repositories
Expand Down
Loading
Loading