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
18 changes: 12 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# CI workflow for stackctl.
# Runs on every push and PR to main/dev branches.
# Validates format, linting, type checking, tests, and coverage.
/**
* CI workflow for stackctl.
*
* Runs on every push and PR to main/dev branches.
* Validates format, linting, type checking, tests, and coverage.
*/
name: CI

on:
Expand Down Expand Up @@ -36,16 +39,19 @@ jobs:
- name: Type check
run: deno task check

- name: Run tests with coverage
run: deno task test --coverage=.coverage
- name: Run tests
run: deno task test

- name: Generate coverage report
if: success()
run: deno task coverage
run: |
deno test --allow-read --allow-write --allow-env --allow-run --allow-sys --coverage=.coverage
deno coverage --detailed .coverage

build:
runs-on: ubuntu-latest
needs: check
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev'
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
71 changes: 71 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

- The use of sexualized language or imagery and unwelcome sexual attention or advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, or to ban temporarily or permanently any
contributor for other behaviors that they deem inappropriate, threatening,
offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at anitrendapp@gmail.com. The project
team will review and investigate all complaints, and will respond in a way that
it deems appropriate to the circumstances. The project team is obligated to
maintain confidentiality with regard to the reporter of an incident. Further
details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 1.4, available at [http://contributor-covenant.org/version/1/4][version].

[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
85 changes: 85 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Contributing

When contributing to this repository, please first discuss the change you wish to make via a GitHub issue, email, or Discord with the owners of this repository before making a change.

Please note we have a [Code of Conduct](CODE_OF_CONDUCT.md), please follow it in all your interactions with the project.

## Issue Guidelines

- Search existing issues for duplicates before creating a new one.
- Keep individual issues for each suggestion, bug, or feature.
- Titles should use a scoped prefix for visibility, for example `[config] Harden profile merge order` or `[generate] Port idempotent stack generation`.
- Use labels for taxonomy such as `feature`, `bug`, `refactor`, or `docs` rather than encoding taxonomy into the title itself.

## Pull Request Guidelines

- Make individual pull requests for each issue, and link the issue in the PR description.
- PR titles follow the format `<type>(<scope>): <brief summary>` and stay aligned with the branch intent.
- Do not stage files excluded by `.gitignore`.
- Commits should reference relevant issues or other PRs.
- Automated pull requests should follow the same branch naming conventions as contributor PRs.

## Quality Standards

Exhaustive unit tests are mandatory for all PRs, demonstrating the cases guarded against and extent of coverage.

### Branch Naming

```
<type>/<issue-number>-<short-description>
```

When no issue number exists yet, use `<type>/<short-description>` temporarily and link the branch to the issue as soon as it is created.

Supported types:

- `feat` -- A new feature
- `fix` -- A bug fix
- `chore` -- Routine tasks, dependencies, and maintenance
- `docs` -- Documentation only changes
- `refactor` -- Code change that neither fixes a bug nor adds a feature
- `test` -- Adding missing or correcting existing tests
- `build` -- Changes that affect the build system or dependencies
- `ci` -- Changes to CI configuration or automation scripts
- `revert` -- Reverting a previous commit

Examples:

- `feat/1208-implement-override-merging`
- `fix/1177-template-drift-in-config-init`
- `docs/1234-update-contributing-guidelines`
- `ci/update-deno-version`

### Commit Messages

```
<type>(<scope>): <brief summary>
```

Scope should be a module area such as `config`, `generate`, `render`, `cli`, `docker`, `secrets`, or `project`.

Examples:

- `feat(config): add profile overlay discovery`
- `fix(render): handle nested $VAR without braces`
- `chore(project): pin Deno version in CI`
- `docs(contributing): clarify PR title format`

### Pull Request Titles

Use the same format `<type>(<scope>): <brief summary>` and keep the title consistent with the branch intent.

### Before Submitting

- Run `deno task check` (fmt, lint, type-check) and fix any issues.
- Run `deno task test` and confirm all tests pass (existing and new).
- Run `deno task coverage` and verify coverage targets are met (minimum 80% line coverage for `src/`).
- Verify that no secrets, credentials, or local paths were committed.

## Code of Conduct

See [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for our community standards and enforcement policies.

---

Thank you for your contribution!
95 changes: 94 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,94 @@
# stackctl
# stackctl

[![CI](https://github.com/AniTrend/stackctl/actions/workflows/ci.yml/badge.svg)](https://github.com/AniTrend/stackctl/actions/workflows/ci.yml)

A Deno-powered CLI for managing local Docker Compose stacks across multi-service repositories, with config-driven profiles, overrides, secrets, and render pipelines.

Status: **Early development** -- all 15 feature issues are planned and tracked on the [issue tracker](https://github.com/AniTrend/stackctl/issues).

---

## Commands

| Command | Status | Description |
|---|---|---|
| `stackctl init` | Planned | Generate commented `.stackctl` config |
| `stackctl generate` | Planned | Generate `stacks/*.yml` from per-service sources |
| `stackctl render` | Planned | Resolve `${VAR}` placeholders in stack files |
| `stackctl overrides` | Planned | Profile and explicit override merging |
| `stackctl up` | Planned | Deploy stacks to Docker Swarm |
| `stackctl down` | Planned | Tear down stacks |
| `stackctl status` | Planned | Show service status |
| `stackctl logs` | Planned | Follow container logs |
| `stackctl sync` | Planned | Sync images and volumes |
| `stackctl doctor` | Planned | Validate environment |
| `stackctl reload` | Planned | Re-render and reconcile without teardown |
| `stackctl secrets` | Planned | Encrypt/decrypt/deploy/clean/check with SOPS+age |
| `stackctl env` | Planned | Scaffold `.env` files from examples |
| `stackctl plan` | Planned | Dry-run summary of all operations |
| `stackctl completions` | Planned | Generate shell completions (bash/zsh/fish) |

---

## Quick Start

```bash
# Install (once released)
deno install -f --allow-run --allow-env --allow-read --allow-write \
-n stackctl jsr:@anitrend/stackctl

# Initialize a config
stackctl init

# Generate stacks from service sources
stackctl generate

# See what would happen
stackctl plan
```

---

## Development

### Prerequisites

- [Deno 2.x](https://deno.com) (2.8.0+)

### Setup

```bash
git clone git@github.com:AniTrend/stackctl.git
cd stackctl

# Run tests
deno task test

# Run checks
deno task check

# Build a binary
deno task build
```

See [CONTRIBUTING.md](CONTRIBUTING.md) for branch naming, commit conventions, and PR guidelines.

---

## License

```
Copyright 2026 AniTrend

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
12 changes: 6 additions & 6 deletions deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
"fmt": "deno fmt",
"fmt:check": "deno fmt --check",
"lint": "deno lint",
"test": "deno test",
"test": "deno test --allow-read --allow-write --allow-env --allow-run --allow-sys",
"coverage": "deno coverage --detailed",
"build": "deno compile --allow-read --allow-write --allow-env --allow-sys --allow-run=git,docker,sops,age,age-keygen,shred,rm --output dist/stackctl src/main.ts",
"build:darwin:x64": "deno compile --target x86_64-apple-darwin --allow-read --allow-write --allow-env --allow-sys --allow-run=git,docker,sops,age,age-keygen,shred,rm --output dist/stackctl-darwin-x64 src/main.ts",
"build:darwin:arm64": "deno compile --target aarch64-apple-darwin --allow-read --allow-write --allow-env --allow-sys --allow-run=git,docker,sops,age,age-keygen,shred,rm --output dist/stackctl-darwin-arm64 src/main.ts",
"build:linux:x64": "deno compile --target x86_64-unknown-linux-gnu --allow-read --allow-write --allow-env --allow-sys --allow-run=git,docker,sops,age,age-keygen,shred,rm --output dist/stackctl-linux-x64 src/main.ts",
"build:linux:arm64": "deno compile --target aarch64-unknown-linux-gnu --allow-read --allow-write --allow-env --allow-sys --allow-run=git,docker,sops,age,age-keygen,shred,rm --output dist/stackctl-linux-arm64 src/main.ts"
"build": "deno compile --output dist/stackctl src/main.ts",
"build:darwin:x64": "deno compile --target x86_64-apple-darwin --output dist/stackctl-darwin-x64 src/main.ts",
"build:darwin:arm64": "deno compile --target aarch64-apple-darwin --output dist/stackctl-darwin-arm64 src/main.ts",
"build:linux:x64": "deno compile --target x86_64-unknown-linux-gnu --output dist/stackctl-linux-x64 src/main.ts",
"build:linux:arm64": "deno compile --target aarch64-unknown-linux-gnu --output dist/stackctl-linux-arm64 src/main.ts"
},
"imports": {
"@cliffy/command": "jsr:@cliffy/command@^1.0.0",
Expand Down
Loading