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
43 changes: 43 additions & 0 deletions .github/workflows/.build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Build

description: Build and Push docker image.

inputs:
docker_username:
description: 'Docker auth username'
required: true
docker_password:
description: 'Docker auth password'
required: true
image:
description: 'Image name / Taskfile command'
required: true

runs:
using: "composite"
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ inputs.docker_username }}
password: ${{ inputs.docker_password }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Buildx
uses: docker/setup-buildx-action@v3
with:
install: true

- name: Invoke Taskfile
uses: Mad-Pixels/github-workflows/.github/actions/taskfile-runner@main
with:
command: ${{ inputs.image }}

29 changes: 29 additions & 0 deletions .github/workflows/.checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Checks

on:
workflow_call:
secrets:
gitleaks:
required: true

jobs:
lint:
name: Lint
runs-on: ${{ vars.RUNS_ON }}
steps:
- name: Invoke
uses: Mad-Pixels/github-workflows/.github/actions/taskfile-runner@main
with:
command: docker/lint

leaks:
name: GitLeaks
runs-on: ${{ vars.RUNS_ON }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_LICENSE: ${{ secrets.gitleaks }}
26 changes: 26 additions & 0 deletions .github/workflows/base_commint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Base commit

on:
push:
branches-ignore:
- main

concurrency:
group: base-commit-${{ github.ref }}
cancel-in-progress: true

jobs:
checks:
name: (Base) Commit Checks
uses: ./.github/workflows/.checks.yml
secrets:
gitleaks: ${{ secrets.GITLEAKS_LICENSE }}

commit-check:
name: (Base) Commit Check
needs: checks
runs-on: ${{ vars.RUNS_ON }}
steps:
- name: All checks passed
run: |
echo "✅ All Commit checks completed successfully!"
39 changes: 39 additions & 0 deletions .github/workflows/main_commit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Main commit

on:
push:
branches:
- main

jobs:
detect-changes:
name: Detect changed directories
runs-on: ${{ vars.RUNS_ON }}
outputs:
dirs: ${{ steps.get-changes.outputs.changes }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Get changes
id: get-changes
uses: Mad-Pixels/github-workflows/.github/actions/taskfile-runner@main
with:
command: changes

build:
needs: detect-changes
if: ${{ needs.detect-changes.outputs.dirs != '' }}
runs-on: ${{ vars.RUNS_ON }}
strategy:
matrix:
dir: ${{ fromJson('["' + join('","', needs.detect-changes.outputs.dirs.split(' ')) + '"]') }}

steps:
- uses: ./.github/workflows/.build.yml
with:
docker_username: ${{ github.actor }}
docker_password: ${{ secrets.GITHUB_TOKEN }}
image: ${{ matrix.dir }}

127 changes: 127 additions & 0 deletions Taskfile.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
version: '3'

vars:
git_root:
sh: git rev-parse --show-toplevel

default_platforms: linux/amd64,linux/arm64
registry: "ghcr.io/mad-pixels"
image_alpine_ver: "3.20"

tasks:
default:
desc: Show usage
cmds:
- echo "Please enter a task or use '-l' or '--list-all' to list all available tasks"
silent: true

# ================================================#
# ---------------------INTERNAL-------------------#
# ================================================#

_docker/buildx:
desc: Internal task to build multiarch images.
internal: true
silent: true
dir: "{{.git_root}}"
cmds:
- |
docker buildx build \
--platform {{.platforms | default .default_platforms}} \
--file {{.dockerfile | default (print .CONTEXT "/Dockerfile")}} \
{{.BUILD_ARGS}} \
-t {{.registry}}/{{.CONTEXT}}:{{.TAG}} \
-t {{.registry}}/{{.CONTEXT}}:latest \
--push \
{{.context_path | default (print "./" .CONTEXT)}}

_docker/run:
desc: Internal task to run secure container.
internal: true
silent: true
dir: "{{.git_root}}"
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}}\
--volume "{{.git_root}}/{{.MOUNT_DIR}}:/workspace:rw" \
{{.IMAGE}} \
{{.CMD}}
requires:
vars: [IMAGE, CMD, MOUNT_DIR]

_docker/lint:
desc: Execute hadolint on single Dockerfile.
internal: true
silent: true
dir: "{{.git_root}}"
cmds:
- task: _docker/run
vars:
IMAGE: "hadolint/hadolint"
MOUNT_DIR: "{{.DOCKERFILE_PATH | dir}}"
CMD: "hadolint {{.DOCKERFILE_PATH | base}}"

# ================================================#
# ---------------------IMAGES---------------------#
# ================================================#

actionlint:
desc: Build actionlint image.
vars:
VERSION: v1.7.7
cmds:
- task: _docker/buildx
vars:
TAG: "{{.VERSION}}"
CONTEXT: actionlint
BUILD_ARGS: >-
--build-arg ALPINE_VERSION={{.image_alpine_ver}}
--build-arg ACTIONLINT_VER={{.VERSION}}
silent: true

taskfile:
desc: Build taskfile image.
vars:
VERSION: v3.44.1
cmds:
- task: _docker/buildx
vars:
TAG: "{{.VERSION}}"
CONTEXT: taskfile
BUILD_ARGS: >-
--build-arg ALPINE_VERSION={{.image_alpine_ver}}
--build-arg TASK_VERSION={{.VERSION}}
silent: true

# ================================================#
# ----------------------CI/CD---------------------#
# ================================================#

docker/lint:
desc: Run hadolint for all Dockerfiles in the repo.
dir: "{{.git_root}}"
vars:
files:
sh: find . -type f -name Dockerfile
cmds:
- for: { var: files }
task: _docker/lint
vars:
DOCKERFILE_PATH: "{{.ITEM}}"

changes:
desc: Get changes Docker directories.
silent: true
cmds:
- |
CHANGES=$(git diff --name-only origin/main HEAD \
| grep '^' \
| cut -d '/' -f1 \
| sort -u \
| grep -E '^(actionlint|taskfile)' || true)
echo "changes=$(echo $CHANGES | xargs)" >> $GITHUB_OUTPUT
16 changes: 16 additions & 0 deletions actionlint/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
ARG ALPINE_VERSION

# build image ->
FROM --platform=$BUILDPLATFORM alpine:${ALPINE_VERSION} AS builder
ARG ACTIONLINT_VER

RUN apk add --no-cache go=latest git=latest
ENV GOPATH=/go \
GOCACHE=/tmp/.cache \
PATH=/go/bin:/usr/local/go/bin:$PATH
RUN go install github.com/rhysd/actionlint/cmd/actionlint@${ACTIONLINT_VER}

# final image ->
FROM --platform=$TARGETPLATFORM scratch
COPY --from=builder /go/bin/actionlint /actionlint
ENTRYPOINT ["/actionlint"]
14 changes: 14 additions & 0 deletions taskfile/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
ARG ALPINE_VERSION

# build stage ->
FROM --platform=$BUILDPLATFORM alpine:${ALPINE_VERSION} AS builder
ARG TASK_VERSION

SHELL ["/bin/ash", "-eo", "pipefail"]
RUN curl -sSL "https://github.com/go-task/task/releases/download/v${TASK_VERSION}/task_linux_$(uname -m).tar.gz" \
| tar -xz -C /usr/local/bin task

# final image ->
FROM --platform=$TARGETPLATFORM alpine:${ALPINE_VERSION}
COPY --from=builder /usr/local/bin/task /usr/local/bin/task
ENTRYPOINT ["task"]
Loading