diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..0672981
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -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.
+
diff --git a/CONCEPT.md b/CONCEPT.md
new file mode 100644
index 0000000..edfbcbc
--- /dev/null
+++ b/CONCEPT.md
@@ -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|
+
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..d735b08
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -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)!
+
diff --git a/README.md b/README.md
index 5d7642e..b2f1125 100644
--- a/README.md
+++ b/README.md
@@ -1,310 +1,69 @@
-
-
-
+
+
+
-# π GitHub Workflows & Actions Library
-
-## Table of Contents
-- [Concept](#concept)
- - [The Problem](#the-problem)
- - [Core Philosophy: Taskfile-Centric Development](#core-philosophy-taskfile-centric-development)
- - [Secure Container Execution](#secure-container-execution)
- - [GitOps-Driven by Design](#gitops-driven-by-design)
- - [Local-to-CI Reproducibility](#local-to-ci-reproducibility)
- - [Deployment: Controlled & Isolated](#deployment-controlled--isolated)
- - [Business Benefits](#business-benefits)
-- [Getting Started](#getting-started)
- - [Prerequisites](#prerequisites)
- - [Step 1: Structure Your Project](#step-1-structure-your-project)
- - [Step 2: Create Secure Container Runtime](#step-2-create-secure-container-runtime)
- - [Step 3: Design Your Task Structure](#step-3-design-your-task-structure)
- - [Step 4: Connect to CI](#step-4-connect-to-ci)
-- [Real-World examples](#real-world-examples)
-- [Contributing](#contributing)
-- [License](#license)
-
-## Concept
-
-### The Problem
-Modern teams often face a gap between local development and CI/CD environments.
-Scripts and tooling are scattered, environments drift, and debugging CI becomes a trial-and-error nightmare.
-
-### Traditional vs Our Approach
-```bash
-βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-β Local Dev CI Environment Production β
-β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
-β β Install β β β Install β β β Yet another β β
-β β deps β β β β different β β β β environment β β
-β β locally.. β β versions.. β β β |
-β β Run tests β β Run CI β β Deploy | |
-β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
-β β β β β
-β βΌ βΌ βΌ β
-β local machine different behavior surprises on Prod β
-β π₯οΈ π© π£ β
-βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-
-βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-β OUR APPROACH β
-βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
-β Local Dev CI Environment Production β
-β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
-β β task lint β β
β taskfile- β β
β Reusable β β
-β β task test β ββ β runner β ββ β Actions β β
-β β task build β β (same tasks)β β (controlled)β β
-β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
-β β β β β
-β βΌ βΌ βΌ β
-β docker containers docker containers GitOps flow β
-β π³ π³ π β
-βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-```
-
-### Core Philosophy: Taskfile-Centric Development
-We define all developer-facing tasks in `Taskfile.yml` ([taskfile](https://taskfile.dev/)), making it the **single source of truth** for every operation:
-- π’ `Consistent across environments` β same commands work locally and in CI
-- π³ `Containerized by default` β all tasks run securely in isolated Docker containers
-- π§ `Empowers developers` β no hidden magic, all tools and commands are transparent and reproducible
-
-### Secure Container Execution
-```bash
-βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-β Host System β
-β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
-β β Docker Container (Hardened) β β
-β β βββββββββββββββββββββββββββββββββββββββββββββββββββ β β
-β β β π --cap-drop=ALL β β β
-β β β π« --security-opt no-new-privileges β β β
-β β β π€ --user $(id -u):$(id -g) β β β
-β β β π /workspace (read-write, project only) β β β
-β β β β β β
-β β β Your Task Execution: β β β
-β β β β’ npm ci && npx eslint . β β β
-β β β β’ cargo test β β β
-β β β β’ go build β β β
-β β βββββββββββββββββββββββββββββββββββββββββββββββββββ β β
-β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
-β π― Result: Isolated, reproducible, secure execution β
-βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-```
-Each task runs in a hardened, ephemeral container:
-- π `Security-first` β dropped capabilities, non-root users, read-only mounts
-- π¦ `Explicit tooling` β versions are locked (e.g. Node 23, Terraform 1.8.5)
-- π `Unified interface` β all orchestration handled by a single internal `_docker/run` task
-
-### GitOps-Driven by Design
-This approach follows GitOps principles:
-- βοΈ `Declarative` β all tasks defined and version-controlled in Git
-- π `Reproducible` β identical environments at every run
-- π΅οΈββοΈ `Auditable` β clear separation between dev and deploy operations
-
-### Local-to-CI Reproducibility
-If it works locally, it works in CI β **guaranteed**:
-- Developers run `task build`, `task lint`, or `task type-check` inside Docker
-- CI invokes the exact same tasks via the `taskfile-runner` GitHub Action
-- No CI-specific scripts or hidden steps
-- Debugging happens locally, not through failed pipelines
-
-### Deployment: Controlled & Isolated
-Deployment operations live in **reusable GitHub Actions**, completely separate from development tasks:
-- π§± `Clear separation` β developers focus on code, platform handles deployment
-- π `Secure by design` β production access restricted to approved CI events
-- π `Reusable workflows` β standardized deployment patterns across projects
-
-### Business Benefits
-- π° `Reduced maintenance cost` β no more "works on my machine" syndrome
-- π `Faster delivery` β fewer environment-specific bugs
-- π `Stronger security` β containerized, read-only, non-root execution
-- π `Clear audit trails` β Git history = deployment history
-- π§ `Better onboarding` β new engineers only need Docker and `task`
-
-## Getting Started
-```bash
-βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-β 1. Local Development β
-β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
-β β task lint βββββΆβ task test βββββΆβ task build β β
-β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
-β β β β β
-β βΌ βΌ βΌ β
-β β
Success β
Success β
Success β
-β β
-β 2. Push to GitHub β
-β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
-β β GitHub Actions runs SAME tasks: β β
-β β β’ taskfile-runner: "lint" β β
-β β β’ taskfile-runner: "test" β β
-β β β’ taskfile-runner: "build" β β
-β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
-β β β β β
-β βΌ βΌ βΌ β
-β β
Success β
Success β
Success β
-β β
-β 3. Deployment (Separate Actions) β
-β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
-β β β’ dockerhub-build-push β β
-β β β’ aws-lambda-restart β β
-β β β’ terraform-runner β β
-β β β’ etc ... β β
-β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
-β π― Guaranteed: Local success = CI success β
-βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-```
-### Prerequisites
-- π³ `Docker` β all tasks run in containers
-- π `Task` β install from [taskfile.dev](https://taskfile.dev/installation/)
-- π `Git` β for version control and workflow triggers
-
-### Step 1: Structure Your Project
-Create the foundation for Taskfile-centric development:
-```bash
-your-project/
-βββ Taskfile.yml # Your development tasks
-βββ .github/
-β βββ workflows/
-β βββ ci.yml # CI using your tasks
-βββ src/ # Your application code
-```
-
-### Step 2: Create Secure Container Runtime
-Establish the foundation for containerized task execution with our proven security pattern:
+# GitHub Workflows & Actions
+This repository contains a collection of reusable **GitHub Actions** and **Reusable Workflows** designed to simplify CI/CD pipelines.
+
+> Each action and workflow is versioned and documented individually.
+> You can browse their respective `README.md` files for details, inputs, outputs, and usage examples.
+
+## Available Actions
+
+### π Taskfile
+| Action | Description |
+|---|---|
+| **[taskfile-runner](./actions/taskfile-runner)** | Execute Taskfile commands |
+
+### π³ Container & Build
+| Action | Description |
+|---|---|
+| **[docker-build-push](./actions/docker-build-push)** | Multi-platform Docker builds |
+
+### βοΈ AWS Infrastructure
+| Action | Description |
+|---|---|
+| **[aws-terraform-runner](./actions/aws-terraform-runner)** | Terraform with S3 backend |
+| **[aws-lambda-restart](./actions/aws-lambda-restart)** | Update Lambda container images |
+| **[aws-s3-sync](./actions/aws-s3-sync)** | Sync directory to S3 |
+| **[aws-cloudfront-invalidation](./actions/aws-cloudfront-invalidation)** | Invalidate CloudFront cache |
+
+### π·οΈ Git Operations
+| Action | Description |
+|---|---|
+| **[github-create-tag](./actions/github-create-tag)** | Create validated git tags |
+| **[github-check-branch](./actions/github-check-branch)** | Validate commit ancestry | |
+
+## Versioning
+
+We use git tags. Pin consumers to stable majors, or exact releases when you need reproducibility. Tags are **repo-wide** (apply to all actions/workflows in this repo).
+
+| Ref | Stability | Description | When to use |
+|---|---|---|---|
+| `@main` | β οΈ Unstable | Latest commit on default branch | Testing and development |
+| `@v1` | β
Stable | Moving major tag (non-breaking updates only) | **Recommended for production** |
+| `@v1.2.3` | β
Stable | Exact released version (immutable) | Reproducible builds, controlled rollouts |
+| `@` | π Frozen | Pinned commit (immutable) | Compliance/audit, maximum control |
+
+**Notes:**
+- Per-action tags like `@action-name/v1` are **not** supported by GitHub; tags are repository-scoped.
+- Breaking changes will bump the major (e.g., `v2`). The `v1` tag will continue to receive backward-compatible updates.
+
+**Examples:**
```yaml
-# Taskfile.yml - Internal task for secure container runtime
-_docker/run:
- internal: true
- cmd: |
- docker run --rm --init {{if .TTY}}-it{{end}} \
- --cap-drop=ALL \
- --security-opt no-new-privileges \
- --user $(id -u):$(id -g) \
- --workdir /workspace \
- {{if .ENVS}}{{range $env := .ENVS}}--env {{$env}} {{end}}{{end}}\
- {{if .PORTS}}{{range $port := .PORTS}}--publish {{$port}} {{end}}{{end}}\
- {{if .VOLUMES}}{{range $vol := .VOLUMES}}--volume {{$vol}} {{end}}{{end}}\
- --volume "{{.git_root}}/{{.MOUNT_DIR}}:/workspace:rw" \
- {{.IMAGE}} \
- {{.CMD}}
- requires:
- vars: [IMAGE, CMD, MOUNT_DIR]
+uses: Mad-Pixels/github-workflows/actions/taskfile-runner@v1
+uses: Mad-Pixels/github-workflows/actions/taskfile-runner@v1.2.3
+uses: Mad-Pixels/github-workflows/actions/github-create-tag@v1
```
-Example usage patterns:
-```yaml
-lint:
- desc: "Run code linting"
- cmds:
- - task: _docker/run
- vars:
- IMAGE: "node:20"
- CMD: "sh -c 'npm ci && npx eslint .'"
- MOUNT_DIR: "."
- ENVS:
- - "NPM_CONFIG_CACHE=/workspace/.cache"
- - "NPM_CONFIG_UPDATE_NOTIFIER=false"
-
-test:
- desc: "Run test suite"
- cmds:
- - task: _docker/run
- vars:
- IMAGE: "golang:1.21"
- CMD: "go test ./..."
- MOUNT_DIR: "."
-
-run_dev:
- desc: Run dev on {{ .dev_port }}.
- cmds:
- - task: _docker/run
- vars:
- IMAGE: "node:{{.node_version}}"
- CMD: "sh -c 'npm ci && npm run dev -- --host 0.0.0.0 --port {{ .dev_port }}'"
- MOUNT_DIR: "."
- PORTS:
- - "{{ .dev_port }}:{{ .dev_port }}"
- ENVS:
- - "NPM_CONFIG_CACHE=/workspace/.cache"
- - "NPM_CONFIG_UPDATE_NOTIFIER=false"
- TTY: "true" # Interactive mode for dev servers
-```
-
-### Step 3: Design Your Task Structure
-Build tasks around developer-facing operations that need local execution and debugging:
-| β
Include in Taskfile examples | β Keep out of Taskfile examples |
-|---------------------------------------------|---------------------------------------|
-| lint for code quality checks | deployment operations |
-| code formatting | infrastructure management |
-| unit and integration tests | production secrets handling |
-| compilation and bundling | cloud resource provisioning |
-| local development server | |
-| static analysis | |
-
-### Step 4: Connect to CI
-Use our [taskfile-runner](https://github.com/Mad-Pixels/github-workflows/blob/main/.github/actions/taskfile-runner/action.yml) action to execute the same tasks in GitHub Actions:
-```yaml
-# .github/workflows/ci.yml
-name: CI Pipeline
-on: [push, pull_request]
-
-jobs:
- quality-checks:
- runs-on: ubuntu-latest
- steps:
- - name: Run linting
- uses: Mad-Pixels/github-workflows/.github/actions/taskfile-runner@main
- with:
- command: "lint"
-
- - name: Run tests
- uses: Mad-Pixels/github-workflows/.github/actions/taskfile-runner@main
- with:
- command: "test"
-
- build:
- runs-on: ubuntu-latest
- steps:
- - name: Build
- uses: Mad-Pixels/github-workflows/.github/actions/taskfile-runner@main
- with:
- command: "build"
-
- # CD part which not implement in Taskfile
- deploy:
- runs-on: ubuntu-latest
- ... your deploy process ...
-```
-
-## Real-World Examples
-To make adoption as smooth as possible, we've prepared several opinionated example projects under [examples/](https://github.com/Mad-Pixels/github-workflows/tree/main/examples).
-Each contains its own `Taskfile.yml` and CI workflow, and is fully runnable out of the box:
-
-| Example | Description |
-|---------------------------------------|---------------------------------------------------------------------------------------------------------------|
-| [nodejs](./examples/flows/nodejs) | Minimal Node.js starter: lint, format, unit tests, build, deploy (external job) and dev server all in Docker. |
-
-### Projects
-| Link | Description |
-|-------------------------------------------------|---------------------------------------|
-| [about](https://github.com/mr-chelyshkin/about) | VueJS static site with AWS deployment |
-| [images](https://github.com/Mad-Pixels/images) | Docker github registry |
+## Support
+- π **Issues:** [GitHub Issues](https://github.com/Mad-Pixels/github-workflows/issues)
+- π¬ **Discussions:** [GitHub Discussions](https://github.com/Mad-Pixels/github-workflows/discussions)
## Contributing
-We β€οΈ community contributions! To get started:
-1. **Fork** the repo and create your feature branch:
-```bash
-git clone git@github.com:Mad-Pixels/.github.git
-cd .github
-git checkout -b feature/my-cool-task
-```
-2. Make your changes in Taskfile.yml, workflows, or docs.
-3. Run the examples locally to verify nothing breaks
-4. Commit your changes
-5. Push and open a Pull Request against `main`.
-6. We'll review, suggest feedback, and merge when ready!
-
-Feel free to open issues for bugs or feature requests, and tag them with appropriate labels.
+We β€οΈ community contributions! Please see our [Contributing Guide](./CONTRIBUTING.md) for details.
## License
This repository is licensed under the [license](./LICENSE) _(Apache License 2.0)_.
diff --git a/actions/aws-cloudfront-invalidation/readme.md b/actions/aws-cloudfront-invalidation/readme.md
index 4cec18c..dd6ba47 100644
--- a/actions/aws-cloudfront-invalidation/readme.md
+++ b/actions/aws-cloudfront-invalidation/readme.md
@@ -40,24 +40,24 @@ jobs:
```
## π₯ Inputs
-| **Name** | **Required** | **Description** | **Default** |
-|--------------------|--------------|---------------------------------------------------------------------------------------------------------|-------------|
-| `aws_region` | β
Yes | AWS region (used by the CLI) | - |
-| `distribution_id` | β
Yes | CloudFront distribution ID (format: E + 13 alphanumeric chars, e.g. `E1234567890ABC`) | - |
-| `aws_access_key` | β No | AWS access key ID (optional if using OIDC) | - |
-| `aws_secret_key` | β No | AWS secret access key (optional if using OIDC) | - |
-| `role_to_assume` | β No | AWS IAM role ARN to assume (OIDC) | - |
-| `paths` | β No | Spaceβseparated list of paths to invalidate (must start with `/`; max 1000 entries; wildcards allowed) | `/*` |
-| `caller_reference` | β No | Custom caller reference for idempotency (autoβgenerated if not provided) | - |
-| `show_summary` | β No | Print summary with task output in job summary | `true` |
-| `summary_limit` | β No | Max number of output lines to show in summary | `250` |
+|**Name**|**Required**|**Description**|**Default**|
+|---|---|---|---|
+|`aws_region`|β
Yes|AWS region (used by the CLI)|-|
+|`distribution_id`|β
Yes|CloudFront distribution ID (format: E + 13 alphanumeric chars, e.g. `E1234567890ABC`)|-|
+|`aws_access_key`|β No|AWS access key ID (optional if using OIDC)|-|
+|`aws_secret_key`|β No|AWS secret access key (optional if using OIDC)|-|
+|`role_to_assume`|β No|AWS IAM role ARN to assume (OIDC)|-|
+|`paths`|β No|Spaceβseparated list of paths to invalidate (must start with `/`; max 1000 entries; wildcards allowed)|`/*`|
+|`caller_reference`|β No|Custom caller reference for idempotency (autoβgenerated if not provided)|-|
+|`show_summary`|β No|Print summary with task output in job summary|`true`|
+|`summary_limit`|β No|Max number of output lines to show in summary|`250`|
## π€ Outputs
-| **Name** | **Description** |
-|-------------------|-------------------------------------|
-| `invalidation_id` | ID of the created invalidation |
-| `status` | Status returned by CloudFront |
-| `caller_reference`| Reference used for this invalidation|
+| **Name**|**Description**|
+|---|---|
+|`invalidation_id`|ID of the created invalidation|
+|`status`|Status returned by CloudFront|
+|`caller_reference`|Reference used for this invalidation|
## π Examples
[View example β](./examples/base.yml)
diff --git a/actions/aws-lambda-restart/readme.md b/actions/aws-lambda-restart/readme.md
index fd108a5..27fc7d6 100644
--- a/actions/aws-lambda-restart/readme.md
+++ b/actions/aws-lambda-restart/readme.md
@@ -44,28 +44,28 @@ jobs:
```
## π₯ Inputs
-| **Name** | **Required** | **Description** | **Default** |
-|--------------------------|--------------|--------------------------------------------------------------------------------------|-------------|
-| `function_name` | β
Yes | Full Lambda function name | - |
-| `aws_region` | β
Yes | AWS region | - |
-| `aws_account_id` | β οΈ Cond. | AWS account ID (12 digits) β required only when using `repository` + `image_tag` | - |
-| `aws_access_key_id` | β No | AWS access key ID (optional if using OIDC) | - |
-| `aws_secret_access_key` | β No | AWS secret access key (optional if using OIDC) | - |
-| `role_to_assume` | β No | AWS IAM role ARN to assume (for OIDC authentication) | - |
-| `image_uri` | β No | Full ECR image URI (overrides `repository`/`image_tag` when provided) | - |
-| `repository` | β No | ECR repository name (used if `image_uri` not provided) | - |
-| `image_tag` | β No | ECR image tag (used with `repository`) | `latest` |
-| `wait_for_update` | β No | Wait for function update to complete (`true`/`false`) | `true` |
-| `show_summary` | β No | Print summary with task output in job summary | `true` |
-| `summary_limit` | β No | Max number of output lines to show in summary | `250` |
+|**Name**|**Required**|**Description**|**Default**|
+|---|---|---|---|
+|`function_name`|β
Yes|Full Lambda function name|-|
+|`aws_region`|β
Yes|AWS region|-|
+|`aws_account_id`|β οΈ Cond.|AWS account ID (12 digits) β required only when using `repository` + `image_tag`|-|
+|`aws_access_key_id`|β No|AWS access key ID (optional if using OIDC)|-|
+|`aws_secret_access_key`|β No|AWS secret access key (optional if using OIDC)|-|
+|`role_to_assume`|β No| AWS IAM role ARN to assume (for OIDC authentication)|-|
+|`image_uri`|β No|Full ECR image URI (overrides `repository`/`image_tag` when provided)|-|
+|`repository`|β No|ECR repository name (used if `image_uri` not provided)|-|
+|`image_tag`|β No|ECR image tag (used with `repository`)|`latest`|
+|`wait_for_update`|β No|Wait for function update to complete (`true`/`false`)|`true`|
+|`show_summary`|β No|Print summary with task output in job summary|`true`|
+|`summary_limit`|β No|Max number of output lines to show in summary|`250`|
## π€ Outputs
-| **Name** | **Description** |
-|------------------|-----------------------------------------|
-| `function_arn` | Lambda function ARN |
-| `last_modified` | Function last modified timestamp |
-| `code_sha256` | Lambda code SHA256 |
-| `imgae_url` | Resolved image URI |
+|**Name**|**Description**|
+|---|---|
+|`function_arn`|Lambda function ARN|
+|`last_modified`|Function last modified timestamp|
+|`code_sha256`|Lambda code SHA256|
+|`imgae_url`|Resolved image URI|
## π Examples
[View example β](./examples/base.yml)
diff --git a/actions/aws-s3-sync/readme.md b/actions/aws-s3-sync/readme.md
index 32f9a4e..cbe720d 100644
--- a/actions/aws-s3-sync/readme.md
+++ b/actions/aws-s3-sync/readme.md
@@ -49,31 +49,31 @@ jobs:
```
## π₯ Inputs
-| **Name** | **Required** | **Description** | **Default** |
-|--------------------------|--------------|---------------------------------------------------------------------------------|----------------------------------------------|
-| `aws_region` | β
Yes | AWS region | - |
-| `bucket_name` | β
Yes | Target S3 bucket name | - |
-| `source_dir` | β
Yes | Local path to sync | - |
-| `aws_access_key` | β No | AWS access key ID (optional if using OIDC) | - |
-| `aws_secret_key` | β No | AWS secret access key (optional if using OIDC) | - |
-| `role_to_assume` | β No | AWS IAM role ARN to assume (OIDC) | - |
-| `bucket_prefix` | β No | Optional subpath prefix inside the bucket (trimmed of leading/trailing slashes) | `""` |
-| `delete_removed` | β No | Remove objects in S3 that are not present in `source_dir` (`true`/`false`) | `true` |
-| `exclude_patterns` | β No | Spaceβseparated exclude patterns passed to `aws s3 sync --exclude` | `.git/* .github/* .gitignore .gitattributes` |
-| `cache_control` | β No | Value for `Cache-Control` header applied to uploads | - |
-| `content_type_detection` | β No | Enable automatic content-type guessing based on file extension (true/false) | true |
-| `show_summary` | β No | Print summary with task output in job summary | `true` |
-| `summary_limit` | β No | Max number of output lines to show in summary | `250` |
+|**Name**|**Required**|**Description**|**Default**|
+|---|---|---|---|
+|`aws_region`|β
Yes|AWS region|-|
+|`bucket_name`|β
Yes|Target S3 bucket name|-|
+|`source_dir`|β
Yes|Local path to sync|-|
+|`aws_access_key`|β No|AWS access key ID (optional if using OIDC)|-|
+|`aws_secret_key`|β No|AWS secret access key (optional if using OIDC)|-|
+|`role_to_assume`|β No|AWS IAM role ARN to assume (OIDC)|-|
+|`bucket_prefix`|β No|Optional subpath prefix inside the bucket (trimmed of leading/trailing slashes)|`""`|
+|`delete_removed`|β No|Remove objects in S3 that are not present in `source_dir` (`true`/`false`)|`true`|
+|`exclude_patterns`|β No|Spaceβseparated exclude patterns passed to `aws s3 sync --exclude`|`.git/* .github/* .gitignore .gitattributes`|
+|`cache_control`|β No|Value for `Cache-Control` header applied to uploads|-|
+|`content_type_detection`|β No|Enable automatic content-type guessing based on file extension (true/false)|true|
+|`show_summary`| β No|Print summary with task output in job summary|`true`|
+|`summary_limit`|β No|Max number of output lines to show in summary|`250`|
## π€ Outputs
-| **Name** | **Description** |
-|-------------------|-------------------------------------------------|
-| `files_uploaded` | Number of uploaded files |
-| `files_deleted` | Number of deleted files |
-| `total_size` | Total size in bytes of local files synced |
-| `file_count` | Total number of local files considered for sync |
-| `sync_duration` | Sync duration in seconds |
-| `s3_url` | Final S3 sync url |
+|**Name**|**Description**|
+|---|---|
+|`files_uploaded`|Number of uploaded files|
+|`files_deleted`|Number of deleted files|
+|`total_size`|Total size in bytes of local files synced|
+|`file_count`|Total number of local files considered for sync|
+|`sync_duration`|Sync duration in seconds|
+|`s3_url`|Final S3 sync url|
## π Examples
[View example β](./examples/base.yml)
diff --git a/actions/aws-terraform-runner/readme.md b/actions/aws-terraform-runner/readme.md
index 8771cb8..452aa66 100644
--- a/actions/aws-terraform-runner/readme.md
+++ b/actions/aws-terraform-runner/readme.md
@@ -48,29 +48,29 @@ jobs:
```
## π₯ Inputs
-| **Name** | **Required** | **Description** | **Default** |
-|-------------------------|--------------|---------------------------------------------------------------------------------|--------------|
-| `backend_bucket` | β
Yes | S3 bucket for storing Terraform state | - |
-| `backend_region` | β
Yes | AWS region for S3 backend | - |
-| `backend_key` | β
Yes | S3 key (path) for Terraform state | - |
-| `aws_region` | β
Yes | AWS region | - |
-| `tf_command` | β
Yes | Terraform command: `plan`, `apply`, or `destroy` | - |
-| `tf_dir` | β
Yes | Path to Terraform configuration directory | - |
-| `aws_access_key_id` | β No | AWS access key ID (optional if using OIDC) | - |
-| `aws_secret_access_key` | β No | AWS secret access key (optional if using OIDC) | - |
-| `role_to_assume` | β No | AWS IAM role ARN for OIDC authentication | - |
-| `tf_workspace` | β No | Terraform workspace name | `""` |
-| `tf_vars` | β No | Extra CLI `-var` flags | `""` |
-| `tf_version` | β No | Terraform version | `1.8.5` |
-| `show_summary` | β No | Print summary with task output in job summary | `true` |
-| `summary_limit` | β No | Max number of output lines to show in summary | `500` |
+|**Name**|**Required**|**Description**|**Default**|
+|---|---|---|---|
+|`backend_bucket`|β
Yes|S3 bucket for storing Terraform state|-|
+|`backend_region`|β
Yes|AWS region for S3 backend|-|
+|`backend_key`|β
Yes|S3 key (path) for Terraform state|-|
+|`aws_region`|β
Yes|AWS region|-|
+|`tf_command`|β
Yes|Terraform command: `plan`, `apply`, or `destroy`|-|
+|`tf_dir`|β
Yes|Path to Terraform configuration directory|-|
+|`aws_access_key_id`|β No| AWS access key ID (optional if using OIDC)|-|
+|`aws_secret_access_key`|β No|AWS secret access key (optional if using OIDC)|-|
+|`role_to_assume`|β No|AWS IAM role ARN for OIDC authentication|-|
+|`tf_workspace`|β No| Terraform workspace name|`""`|
+|`tf_vars`|β No| Extra CLI `-var` flags|`""`|
+|`tf_version`|β No|Terraform version|`1.8.5`|
+|`show_summary`|β No| Print summary with task output in job summary|`true`|
+|`summary_limit`|β No| Max number of output lines to show in summary|`500`|
## π€ Outputs
-| **Name** | **Description** |
-|---------------------|----------------------------------------------------------|
-| `terraform_command` | Executed Terraform command (`plan`/`apply`/`destroy`) |
-| `workspace` | Workspace used during execution |
-| `terraform_version` | Used terraform version |
+|**Name**|**Description**|
+|---|---|
+|`terraform_command`|Executed Terraform command (`plan`/`apply`/`destroy`)|
+|`workspace`|Workspace used during execution|
+|`terraform_version`|Used terraform version|
## π Examples
[View example β](./examples/base.yml)
diff --git a/actions/docker-build-push/readme.md b/actions/docker-build-push/readme.md
index 16561b9..6be6990 100644
--- a/actions/docker-build-push/readme.md
+++ b/actions/docker-build-push/readme.md
@@ -49,29 +49,29 @@ jobs:
```
## π₯ Inputs
-| **Name** | **Required** | **Description** | **Default** |
-|------------------|--------------|-----------------------------------------------------------------------------------------------------|---------------------------------------------|
-| `docker_user` | β
Yes | Registry username (Docker Hub by default) | - |
-| `docker_token` | β
Yes | Registry access token / password | - |
-| `repository` | β
Yes | Image repository (e.g. `user/image` or `ghcr.io/org/image` with non-default registry) | - |
-| `tag` | β
Yes | Image tag (e.g. `v1.0.0`, `sha`) | - |
-| `registry` | β No | Registry host (e.g. `docker.io`, `ghcr.io`) | `docker.io` |
-| `push_latest` | β No | Also tag and push `:latest` (`true`/`false`) | `false` |
-| `platforms` | β No | Target platforms (comma-separated) | `linux/amd64,linux/arm64` |
-| `build_args` | β No | Build args as JSON object (values kept intact; requires valid JSON) | `{}` |
-| `artifact_name` | β No | If set, downloads artifact and uses it as build context | `''` |
-| `context_path` | β No | Build context path (relative to repo root or artifact root) | `.` |
-| `dockerfile_path`| β No | Path to Dockerfile (relative to `context_path`) | `Dockerfile` |
-| `show_summary` | β No | Print summary with task output in job summary | `true` |
-| `summary_limit` | β No | Max number of output lines to show in summary | `250` |
+|**Name**|**Required**|**Description**|**Default**|
+|---|---|---|---|
+|`docker_user`|β
Yes|Registry username (Docker Hub by default)|-|
+|`docker_token`|β
Yes|Registry access token / password|-|
+|`repository`|β
Yes|Image repository (e.g. `user/image` or `ghcr.io/org/image` with non-default registry)|-|
+|`tag`|β
Yes|Image tag (e.g. `v1.0.0`, `sha`)|-|
+|`registry`|β No|Registry host (e.g. `docker.io`, `ghcr.io`)|`docker.io`|
+|`push_latest`|β No|Also tag and push `:latest` (`true`/`false`)|`false`|
+|`platforms`|β No|Target platforms (comma-separated)|`linux/amd64,linux/arm64`|
+|`build_args`|β No|Build args as JSON object (values kept intact; requires valid JSON)|`{}`|
+|`artifact_name`|β No|If set, downloads artifact and uses it as build context|`''`|
+|`context_path`|β No|Build context path (relative to repo root or artifact root)|`.`|
+|`dockerfile_path`|β No|Path to Dockerfile (relative to `context_path`)|`Dockerfile`|
+|`show_summary`|β No|Print summary with task output in job summary|`true`|
+|`summary_limit`|β No|Max number of output lines to show in summary| `250`|
## π€ Outputs
-| **Name** | **Description** |
-|-----------------|------------------------------------------|
-| `image_digest` | Pushed image manifest-list digest (sha) |
-| `build_duration`| Duration in sec |
-| `image_size` | Size in bytes |
-| `image_ref` | Fully qualified `image@digest` |
+|**Name**|**Description**|
+|---|---|
+|`image_digest`|Pushed image manifest-list digest (sha)|
+|`build_duration`|Duration in sec|
+|`image_size`|Size in bytes|
+|`image_ref`|Fully qualified `image@digest`|
## π Examples
[View example β](./examples/base.yml)
diff --git a/actions/github-check-branch/readme.md b/actions/github-check-branch/readme.md
index 203ced3..aff57fc 100644
--- a/actions/github-check-branch/readme.md
+++ b/actions/github-check-branch/readme.md
@@ -37,23 +37,23 @@ jobs:
```
## π₯ Inputs
-| **Name** | **Required** | **Description** | **Default** |
-|-------------------|--------------|--------------------------------------------------------------|-------------|
-| `target_branch` | β No | Branch to validate against (e.g., `main`, `release/v1`) | `main` |
-| `tag_name` | β No | Tag name to validate; if empty, validates current `HEAD` | ` ` |
-| `commit_sha` | β No | Explicit commit SHA to validate (overrides `tag_name/HEAD`) | ` ` |
-| `fail_on_invalid` | β No | Fail the action if not reachable ('true'/'false') | ` ` |
-| `show_summary` | β No | Print summary with task output in job summary | `true` |
-| `summary_limit` | β No | Max number of output lines to show in summary | `250` |
+|**Name**|**Required**|**Description**|**Default**|
+|---|---|---|---|
+|`target_branch`|β No|Branch to validate against (e.g., `main`, `release/v1`)|`main`|
+|`tag_name`|β No|Tag name to validate; if empty, validates current `HEAD`|` `|
+|`commit_sha`|β No|Explicit commit SHA to validate (overrides `tag_name/HEAD`)|` `|
+|`fail_on_invalid`|β No|Fail the action if not reachable ('true'/'false')|` `|
+|`show_summary`|β No|Print summary with task output in job summary|`true`|
+|`summary_limit`|β No|Max number of output lines to show in summary|`250`|
## π€ Outputs
-| **Name** | **Description** |
-|-----------------|------------------------------------------------------------------------------|
-| `is_valid` | `true` if commit/tag is reachable from target branch, else `false` |
-| `commit` | The validated commit SHA |
-| `subject` | What was validated (`HEAD:`, `tag:`, or `commit:`) |
-| `target_branch` | The branch used for validation |
-| `merge_base` | Common ancestor SHA (only set when validation fails and histories intersect) |
+|**Name**|**Description**|
+|---|---|
+|`is_valid`|`true` if commit/tag is reachable from target branch, else `false`|
+|`commit`|The validated commit SHA|
+|`subject`|What was validated (`HEAD:`, `tag:`, or `commit:`)|
+|`target_branch`|The branch used for validation|
+|`merge_base`|Common ancestor SHA (only set when validation fails and histories intersect)|
## π Examples
[View example β](./examples/base.yml)
diff --git a/actions/github-create-tag/readme.md b/actions/github-create-tag/readme.md
index 6f708c7..7ee4865 100644
--- a/actions/github-create-tag/readme.md
+++ b/actions/github-create-tag/readme.md
@@ -48,24 +48,24 @@ jobs:
```
## π₯ Inputs
-| **Name** | **Required** | **Description** | **Default** |
-|----------------|--------------|---------------------------------------------------------------------------|-----------------------------------|
-| `tag` | β
Yes | Tag to create (e.g., v1.2.3) | - |
-| `token` | β
Yes | GitHub token or PAT with `contents: write` permissions | - |
-| `force` | β No | Overwrite existing tag if it exists (`true`/`false`) | `false` |
-| `branch` | β No | Branch to tag from | `main` |
-| `tag_format` | β No | Regex to validate tag format | `^v[0-9]+\.[0-9]+\.[0-9]+(-.*)?$` |
-| `message` | β No | Message for annotated tag (ignored for lightweight tags) | - |
-| `lightweight` | β No | Create lightweight tag (overrides message) (`true`/`false`) | `false` |
-| `show_summary` | β No | Print summary with task output in job summary | `true` |
-| `summary_limit`| β No | Max number of output lines to show in summary | `250` |
+|**Name**|**Required**|**Description**|**Default**|
+|---|---|---|---|
+|`tag`|β
Yes|Tag to create (e.g., v1.2.3)|-|
+|`token`|β
Yes|GitHub token or PAT with `contents: write` permissions|-|
+|`force`|β No|Overwrite existing tag if it exists (`true`/`false`)|`false`|
+|`branch`|β No|Branch to tag from|`main`|
+|`tag_format`|β No|Regex to validate tag format|`^v[0-9]+\.[0-9]+\.[0-9]+(-.*)?$`|
+|`message`|β No| Message for annotated tag (ignored for lightweight tags)|-|
+|`lightweight`|β No|Create lightweight tag (overrides message) (`true`/`false`)|`false`|
+|`show_summary`|β No|Print summary with task output in job summary|`true`|
+|`summary_limit`|β No|Max number of output lines to show in summary|`250`|
## π€ Outputs
-| **Name** | **Description** |
-|--------------|--------------------------------------------------|
-| `tag_sha` | SHA of the commit the tag points to |
-| `tag_exists` | Whether the tag already existed before creation |
-| `tag_url` | GitHub URL to view the created tag |
+|**Name**|**Description**|
+|---|---|
+|`tag_sha`|SHA of the commit the tag points to|
+|`tag_exists`|Whether the tag already existed before creation|
+|`tag_url`|GitHub URL to view the created tag|
## π Examples
[lightweight β](./examples/lightweight.yml)
diff --git a/actions/taskfile-runner/readme.md b/actions/taskfile-runner/readme.md
index c17d6fc..703051c 100644
--- a/actions/taskfile-runner/readme.md
+++ b/actions/taskfile-runner/readme.md
@@ -32,21 +32,21 @@ jobs:
```
## π₯ Inputs
-| **Name** | **Required** | **Description** | **Default** |
-|-----------------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------|-------------|
-| `command` | β
Yes | Name of the task to run (e.g. build, test, lint) | - |
-| `vars` | β No | Comma-separated key=value pairs. Values may contain = and newlines; commas are not allowed. Leading/trailing spaces around pairs are trimmed | - |
-| `dir` | β No | Working directory for the Taskfile | `.` |
-| `version` | β No | Version of go-task to install | `3.44.1` |
-| `show_summary` | β No | Print summary with task output in job summary | `true` |
-| `summary_limit` | β No | Max number of output lines to show in summary | `250` |
+|**Name**|**Required**|**Description**|**Default**|
+|---|---|---|---|
+|`command`|β
Yes|Name of the task to run (e.g. build, test, lint)|-|
+|`vars`|β No|Comma-separated key=value pairs. Values may contain = and newlines; commas are not allowed. Leading/trailing spaces around pairs are trimmed|-|
+|`dir`|β No| Working directory for the Taskfile|`.`|
+|`version`|β No| Version of go-task to install|`3.44.1`|
+|`show_summary`|β No| Print summary with task output in job summary|`true`|
+|`summary_limit`|β No| Max number of output lines to show in summary|`250`|
## π€ Outputs
-| **Name** | **Description** |
-|----------------|------------------------------------|
-| `task_version` | Installed Task version |
-| `task_command` | Task command |
-| `task_output` | Complete output from task command |
+|**Name**|**Description**|
+|---|---|
+|`task_version`|Installed Task version|
+|`task_command`|Task command|
+|`task_output`|Complete output from task command|
## π Examples
[View example β](./examples/base.yml)