Scaffold Cloudron packaging workspace

This commit is contained in:
2025-10-02 13:39:36 -05:00
parent 482d4ff1b8
commit fe0ade1dd9
366 changed files with 4035 additions and 2493 deletions

View File

@@ -1,6 +1,6 @@
# Application Status
_Updated: 2025-10-02T16:50:06Z_
_Updated: 2025-10-02T17:22:39Z_
| Slug | Title | Version | Status | Issue |
| --- | --- | --- | --- | --- |

View File

@@ -14,22 +14,26 @@ This project uses the Gitea Actions runner and the built-in container registry h
## Workflow overview
The manual `workflow_dispatch` job builds the `docker/ci-runner` image, then executes `scripts/ci_local.sh` with the requested task list (default `all`). This mirrors the local harness, so whatever succeeds locally will succeed in CI.
The manual `workflow_dispatch` job builds the CI image and then executes the same commands you run locally via:
> Re-enable push/PR triggers once a runner is available and `make ci-local` is consistently green.
```bash
./run/dev.sh python scripts/lint_repo.py --slug apache-apisix --strict
./run/dev.sh python scripts/generate_status.py --preserve-timestamp
```
> Re-enable push/PR triggers once a runner is available and the commands above consistently succeed.
## Container registry usage
- Tag Cloudron packages against the registry namespace, e.g. `git.knownelement.com/knel/cloudron/apache-apisix:<version>`.
- The packager helper script reads `IMAGE_NAME`; override it when pushing to the registry:
- Build and push images directly via Docker:
```bash
IMAGE_NAME=git.knownelement.com/knel/cloudron-packager BUILD=1 scripts/run_packager.sh
docker build -t git.knownelement.com/knel/cloudron-packager docker/packager
docker push git.knownelement.com/knel/cloudron-packager
```
- Cloudrons CLI can push directly to the registry once you log in within the packager container.
- Cloudrons CLI can push directly to the registry once you log in within the packager shell (`./run/packager.sh`).
## Future enhancements
- Add `make lint` and `make status` as required checks in Gitea branch protection.
- Add lint/status checks as required gates in Gitea branch protection.
- Extend the workflow with matrix builds for priority apps (e.g. run smoke scripts once implemented).

View File

@@ -1,33 +1,20 @@
# Local Test Harness
All verification runs locally inside Docker containers so your workstation matches the eventual Gitea Actions runner exactly.
All verification runs through the wrapper scripts under `run/`, ensuring every command executes in Docker.
## CI-equivalent container
## Devtools checks
- `docker/ci-runner/Dockerfile` builds the image `knel/cloudron-ci`, derived from the same base the Gitea runner will use.
- `scripts/ci_local.sh` orchestrates tasks inside that container. Run `BUILD=1 ./scripts/ci_local.sh lint` the first time to build the image.
- Tasks:
- `lint``make lint` + `make status` + `git diff docs/APP_STATUS.md`
- `packager-smoke` → builds `docker/packager` and runs `cloudron --help`
- `all` (default) → runs both.
The script mounts `/var/run/docker.sock` so Docker CLI calls inside the container reuse the host daemon.
## Git hooks
Use `scripts/hooks/install_hooks.sh` to install local hooks:
Use `./run/dev.sh` for linting and documentation updates:
```bash
./scripts/hooks/install_hooks.sh
./run/dev.sh python scripts/lint_repo.py --slug apache-apisix --strict
./run/dev.sh python scripts/generate_status.py --preserve-timestamp
```
- `pre-commit` runs `./scripts/ci_local.sh lint`.
- `post-commit` refreshes `docs/APP_STATUS.md` (non-fatal).
- `pre-push` runs the packager smoke test.
## Packaging shell
Set `SKIP_CI_HOOKS=1` when you need to bypass the hooks temporarily.
Invoke `./run/packager.sh` (optionally with `BUILD=1`) when you need the Cloudron CLI to build, install, or push packages.
## Alignment with Gitea Actions
The `.gitea/workflows/ci.yml` workflow wraps the same `scripts/ci_local.sh` entrypoint and is currently manual-only (`workflow_dispatch`). Enable push/PR triggers once a runner is provisioned.
## CI parity
The Gitea workflow calls the same commands via the devtools image. To mimic it locally, run the lint/status commands above followed by any smoke tests inside the packager shell.

View File

@@ -4,79 +4,92 @@ This repository standardises the workflow for building and maintaining Cloudron
## Reference workflow
1. Generate a package scaffold from the shared template using `scripts/new_app.py`.
2. Run all build, test, and release tasks inside the `docker/packager` container to avoid host pollution.
3. Implement application-specific build steps in `apps/<slug>/Dockerfile` and configure the runtime via `start.sh`.
4. Update `CloudronManifest.json` with accurate metadata, addons, ports, and health checks based on the upstream project.
5. Build and test locally with the Cloudron CLI (`cloudron build`, `cloudron install --app <domain>`) inside the packaging container.
6. Push the image to the Cloudron registry (`cloudron push`) and publish once happy with smoke-test coverage.
1. Build or refresh the devtools image when dependencies change:
```bash
./run/dev.sh python --version
```
2. Enter an interactive devtools shell so every command runs inside Docker:
```bash
./run/dev.sh bash --login
```
3. Implement application-specific build steps in `apps/<slug>/Dockerfile` and configure runtime behaviour through `start.sh`.
4. Update `CloudronManifest.json` with accurate metadata, addons, ports, and health checks.
5. Build and test using the devtools shell or one-off wrappers.
6. Push new images via the Cloudron packager shell when smoke tests pass.
## Cloudron packaging essentials
- **Base image**: Start from `cloudron/base:<version>` and add only the dependencies the app requires.
- **CloudronManifest**: The manifest declares metadata, exposed ports, resource limits, addons (databases, object storage, email), and health checks. Always keep the `id` stable since it uniquely identifies the package inside Cloudron ecosystems.
- **Start script**: Use `start.sh` to render configuration from environment variables and launch the primary process under the `cloudron` user.
- **Tests**: Provide smoke tests in `test/` that Cloudron can run via `cloudron build --test`.
- **Updates**: Bump the manifest `version`, document the change in `changelog`, and rebuild when upstream releases.
- **Base image:** The runtime stage **must** derive from `cloudron/base:<version>`; use a dedicated builder stage to compile artefacts and copy only what you need.
- **CloudronManifest:** Declare metadata, exposed ports, resource limits, addons, and health checks. Keep `id` stable and set realistic limits per app.
- **Start script:** Render configuration from environment variables and launch the primary process as `cloudron`.
- **Tests:** Provide smoke tests in `test/` so `cloudron build --test` can validate deployments.
- **Updates:** Bump the manifest `version`, document the change in `changelog`, and rebuild for upstream releases.
## Repository linting
Run the scaffold lint checks after editing an app to catch placeholder artefacts:
Run lint checks entirely through the devtools wrapper:
```bash
python3 scripts/lint_repo.py
./run/dev.sh python scripts/lint_repo.py --slug apache-apisix --strict
```
Set `CLOUDRON_BASE` to override the expected base image version when needed.
Add `--base-prefix` if you intentionally change the final base image prefix.
Use the Makefile shortcuts for common tasks:
## Common workflows
Interactive session (recommended while iterating):
```bash
make scaffold # regenerate scaffolds from catalog
make lint # run repo lint checks
make status # refresh docs/APP_STATUS.md
./run/dev.sh bash --login
# inside the container
python scripts/new_app.py --slug apache-apisix
python scripts/new_app.py --force
python scripts/lint_repo.py --slug apache-apisix --strict
python scripts/generate_status.py --preserve-timestamp
```
Leverage the Gitea Actions workflow (`.gitea/workflows/ci.yml`) to enforce `make lint` and status generation on every push; instructions for runner setup live in `docs/CI_CD_GITEA.md`.
Non-interactive equivalents:
Run the local harness via `./scripts/ci_local.sh` (or `make ci-local`) to replicate the CI pipeline without relying on a remote runner; see `docs/LOCAL_TESTING.md` for hook integration.
```bash
./run/dev.sh python scripts/new_app.py --slug apache-apisix
./run/dev.sh python scripts/new_app.py --force
./run/dev.sh python scripts/lint_repo.py --slug apache-apisix --strict
./run/dev.sh python scripts/generate_status.py --preserve-timestamp
```
## Using the packager container
```bash
# Build the helper image
BUILD=1 scripts/run_packager.sh
Open the Cloudron packaging environment via:
# Launch an interactive shell inside the packaging environment
scripts/run_packager.sh
```bash
./run/packager.sh
```
The container bundles the Cloudron CLI, Docker CLI, git, curl, and other tooling for reproducible builds. The host Docker socket is mounted so you can reuse local credentials while keeping the host clean.
Pass `BUILD=1` to rebuild the image before launching (`BUILD=1 ./run/packager.sh`). Use this shell for `cloudron build`, `cloudron install`, and `cloudron push` operations.
## Adding a new application
```bash
# Create the full scaffold for all catalog entries
python3 scripts/new_app.py
Generate scaffolds with the devtools wrapper:
# Or generate a single skeleton
python3 scripts/new_app.py --slug apache-apisix
```bash
./run/dev.sh python scripts/new_app.py --force # regenerate entire catalog
./run/dev.sh python scripts/new_app.py --slug apache-apisix
```
Each scaffold contains:
- `Dockerfile` build instructions
- `Dockerfile` multi-stage build instructions
- `start.sh` runtime entrypoint
- `CloudronManifest.json` metadata and permissions
- `test/smoke.sh` placeholder smoke test
- `metadata.json` issue and upstream bookkeeping
- `README.md` packaging checklist
Update these files with the app-specific details, add upstream artefacts under `app/`, and commit the changes.
Update these files with app-specific details, add artefacts under `app/`, and commit the changes.
## Repository etiquette
- Document design decisions and manual steps in `docs/` or the per-app README.
- Keep automation scripts idempotent; rerunning them should not damage uncommitted work.
- Use semantic versioning in manifest files (`MAJOR.MINOR.PATCH`).