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
29 changes: 29 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
## Description
Brief description of what this PR does.

## Title Format
- [ ] Title starts with tag: `[feat]`, `[fix]`, `[refactor]`, `[docs]`, `[chore]`

## Type of Change
- [ ] 🐛 Bug fix
- [ ] ✨ New feature
- [ ] 💥 Breaking change
- [ ] 📚 Documentation
- [ ] 🔧 Refactoring

## Testing
- [ ] Linting passes (`task yamllint`)
- [ ] Tested with examples
- [ ] Documentation updated

## Action-Specific
- [ ] Follows input standards (`show_summary`, validation)
- [ ] Includes README with inputs/outputs
- [ ] Examples provided

## Issue
Add issue if relevant

## Notes
Additional context or concerns.

164 changes: 164 additions & 0 deletions CONCEPT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# Concept: Taskfile-Centric Development
## Why
Teams waste time fighting environment drift between local dev and CI.
Scripts scatter across repos, CI has hidden steps, and debugging becomes trial-and-error.
We fix this by making **Taskfile the single source of truth** and running everything in **secure containers** — locally and in CI.

## Who This Is For
- Teams with complex build/test pipelines
- Infrastructure-heavy projects (AWS, Terraform, CD)
- Organizations wanting reproducibility and quick onboarding

## Core Principles
1. **Reproducibility** — same Task runs identically everywhere
2. **Isolation** — no host dependencies beyond Docker + Task
3. **Security by default** — non-root, dropped caps, no-new-privileges
4. **Transparency** — no CI-only magic; everything in `Taskfile.yml`
5. **Separation of concerns** — CI (dev tasks) in Taskfile; CD (deploy) in Actions

## Container Security Defaults
- `--cap-drop=ALL` — no privileged capabilities
- `--security-opt no-new-privileges` — prevent privilege escalation
- `--user $(id -u):$(id -g)` — non-root execution
- `--workdir /workspace` — consistent working directory
- Project mount only: `/workspace` (read-write)

## Container Runtime Pattern
Pull image once (quiet):
```yaml
_docker/pull:
internal: true
cmds:
- |
if ! docker image inspect "{{.IMAGE}}" >/dev/null 2>&1; then
docker pull -q "{{.IMAGE}}" >/dev/null 2>&1 || {
echo "Failed to pull image: {{.IMAGE}}"
exit 1
}
fi
silent: true
requires:
vars: [IMAGE]
```
Run securely (never pull during execution):
```yaml
_docker/run:
internal: true
dir: "{{.git_root}}"
deps:
- task: _docker/pull
vars: { IMAGE: "{{.IMAGE}}" }
cmd: |
docker run --rm --init --pull=never {{if .TTY}}-it{{end}} \
--cap-drop=ALL \
--security-opt no-new-privileges \
--user $(id -u):$(id -g) \
--workdir /workspace \
{{if .ENVS}}{{range $e := .ENVS}}--env {{$e}} {{end}}{{end}}\
{{if .PORTS}}{{range $p := .PORTS}}--publish {{$p}} {{end}}{{end}}\
{{if .VOLUMES}}{{range $v := .VOLUMES}}--volume {{$v}} {{end}}{{end}}\
--volume "{{.git_root}}/{{.MOUNT_DIR}}:/workspace:rw" \
"{{.IMAGE}}" \
{{.CMD}}
silent: true
requires:
vars: [IMAGE, CMD, MOUNT_DIR]
```

### Runtime Variables
| Variable | Purpose | Example |
|---|---|---|
|`IMAGE`|Docker image (pin in CI)|`node:20`, `golang:1.22@sha256:...`|
|`CMD`|Command to execute|`sh -c 'npm ci && npm test'`|
|`MOUNT_DIR`|Project directory to mount|`"."`, `"site"`, `"infra"`|
|`ENVS`|Environment variables|`["GOOS=linux","NPM_CONFIG_CACHE=/cache"]`|
|`PORTS`|Port mappings for dev servers|`["3000:3000"]`|
|`VOLUMES`|Additional mounts|`["$HOME/.ssh:/ssh:ro"]`|
|`TTY`|Interactive mode|`"true"` for dev servers|

## Task Examples
```yaml
lint:
desc: "Run code linting"
cmds:
- task: _docker/run
vars:
IMAGE: "node:20"
MOUNT_DIR: "."
ENVS: ["NPM_CONFIG_CACHE=/workspace/.cache"]
CMD: "sh -c 'npm ci && npx eslint .'"

test:
desc: "Run test suite"
cmds:
- task: _docker/run
vars:
IMAGE: "golang:1.22"
MOUNT_DIR: "."
CMD: "go test ./..."

dev:
desc: "Development server with hot reload"
cmds:
- task: _docker/run
vars:
IMAGE: "node:20"
MOUNT_DIR: "."
PORTS: ["3000:3000"]
TTY: "true"
CMD: "sh -c 'npm ci && npm run dev -- --host 0.0.0.0'"
```

## CI Integration
Use the same tasks in GitHub Actions:
```yaml
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: Mad-Pixels/github-workflows/actions/taskfile-runner@v1
with:
command: "lint"

- uses: Mad-Pixels/github-workflows/actions/taskfile-runner@v1
with:
command: "test"
```

## What Goes Where
|✅ Include in Taskfile|❌ Keep in Actions|
|---|---|
|Code linting/formatting|AWS deployments|
|Unit/integration tests|Infrastructure provisioning|
|Building/compilation|Production secrets handling|
|Development servers|Cloud resource management|
|Static analysis|Terraform apply operations|

## Benefits
- 💰 **Reduced maintenance** — no more "works on my machine"
- 🚀 **Faster delivery** — fewer environment-specific bugs
- 🔐 **Stronger security** — containerized, non-root execution
- 📋 **Clear audit trails** — Git history = deployment history
- 🧠 **Better onboarding** — new engineers only need Docker and Task

## Local-to-CI Guarantee
If it works locally, it works in CI — **guaranteed**:
- Same Docker images and commands
- Same environment variables and mounts
- No CI-specific scripts or hidden steps
- Debug locally, not through failed pipelines

## Best Practices
- **Pin images by digest in CI** for determinism: `node:20@sha256:...`
- **Use project-local caches** under `/workspace/.cache`
- **Mount read-only where possible**: `["$HOME/.ssh:/ssh:ro"]`
- **Validate inputs** in task descriptions and error messages
- **Keep secrets out of Taskfile** — handle via Actions only

## Real Project Examples
| Name | Description |
|---|---|
|**[about](https://github.com/mr-chelyshkin/about)**|VueJS static site with containerized build and AWS deployment|

100 changes: 100 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Contributing Guide

Thank you for your interest in contributing to GitHub Workflows & Actions!

## Project Structure
```bash
.
├── actions/ # All reusable actions
│ ├── action-name/
│ │ ├── action.yml # Action definition
│ │ ├── readme.md # Documentation
│ │ └── examples/ # Usage examples
│ └── internal/ # Internal composite actions
├── .github/workflows/ # CI/CD workflows
├── Taskfile.yml # Development tasks
└── README.md # Main documentation
```

## Getting Started
### Prerequisites
- [Task CLI](https://taskfile.dev/installation/)
- Docker
- Git

### Development Workflow
1. `Fork and clone` the repository
2. `Create a feature branch`:
```bash
git checkout -b feature/my-new-action
```
3. `Run linting`:
```bash
task yamllint
```
4. `Test your changes` using example workflows

## Adding a New Action
1. **Create directory structure**:
```bash
actions/my-new-action/
├── action.yml
├── readme.md
└── examples/
└── base.yml
```
2. **Follow existing patterns**:
- Look at [docker-build-push](./actions/docker-build-push/) as reference
- Use composite actions for shell scripts
- Validate all inputs
- Provide clear error messages

3. **Documentation requirements**:
- Complete `readme.md` with inputs/outputs tables
- Practical usage examples
- Prerequisites and limitations

4. **Testing**:
- Add example workflow in `examples/`
- Test manually with the example
- Ensure `task yamllint` passes

## Action Standards
### Required Inputs
All actions must include these standard inputs:
```yaml
show_summary:
description: 'Print summary in the job summary'
required: false
default: 'true'
```

### Summary Implementation
- Generate job summary using `$GITHUB_STEP_SUMMARY`
- Respect `show_summary` inputs
- Include key outputs, status, and relevant details

## Code Standards
- **YAML**: Follow `.yamllint.yml` rules
- **Shell scripts**: Use `set -euo pipefail`
- **Security**: Follow principle of least privilege
- **Error handling**: Fail fast with clear messages

## Submitting Changes
1. **Test thoroughly**:
```bash
task yamllint
```
2. **Commit with clear messages**:
```bash
git commit -m "[feat] add new action for xyz"
```
3. **Push and create PR**:
- Describe what the action does
- Include usage examples
- Reference any related issues

## Questions?
Open an [issue](https://github.com/Mad-Pixels/github-workflows/issues)
or start a [discussion](https://github.com/Mad-Pixels/github-workflows/discussions)!

Loading