diff --git a/.github/workflows/cicd.yaml b/.github/workflows/cicd.yaml new file mode 100644 index 0000000..cd01f84 --- /dev/null +++ b/.github/workflows/cicd.yaml @@ -0,0 +1,61 @@ +--- +name: "Continuous Integration: Build and Publish Multi-Architecture Container Images" +# This is the generic reusable template for building containers + +'on': + workflow_dispatch: {} + push: + branches: + - dev + pull_request: + branches: + - main + +jobs: + check: + uses: gautada/cicd/.github/workflows/ci-linter.yaml@main + deep-scan: + needs: check + uses: gautada/cicd/.github/workflows/ci-deep-scan.yaml@main + build-arm64: + needs: check + uses: gautada/cicd/.github/workflows/ci-podman-build.yaml@main + with: + architecture: "arm64" + secrets: + REGISTRY_USERNAME: ${{ secrets.DOCKERIO_REGISTRY }} + REGISTRY_TOKEN: ${{ secrets.DOCKERIO_TOKEN }} + build-amd64: + needs: check + uses: gautada/cicd/.github/workflows/ci-podman-build.yaml@main + with: + architecture: "amd64" + secrets: + REGISTRY_USERNAME: ${{ secrets.DOCKERIO_REGISTRY }} + REGISTRY_TOKEN: ${{ secrets.DOCKERIO_TOKEN }} + publish: + needs: [build-arm64, build-amd64] + uses: gautada/cicd/.github/workflows/ci-podman-publish.yaml@main + with: + architectures: '["arm64", "amd64"]' + secrets: + REGISTRY_USERNAME: ${{ secrets.DOCKERIO_REGISTRY }} + REGISTRY_TOKEN: ${{ secrets.DOCKERIO_TOKEN }} + clean: + needs: [publish] + uses: gautada/cicd/.github/workflows/ci-registry-clean.yaml@main + secrets: + REGISTRY_USERNAME: ${{ secrets.DOCKERIO_REGISTRY }} + REGISTRY_TOKEN: ${{ secrets.DOCKERIO_TOKEN }} + test: + needs: [clean] + uses: gautada/cicd/.github/workflows/ci-container-test.yaml@main + secrets: + REGISTRY_USERNAME: ${{ secrets.DOCKERIO_REGISTRY }} + REGISTRY_TOKEN: ${{ secrets.DOCKERIO_TOKEN }} + release: + needs: [test] + uses: gautada/cicd/.github/workflows/cd-tag-latest.yaml@main + secrets: + REGISTRY_USERNAME: ${{ secrets.DOCKERIO_REGISTRY }} + REGISTRY_TOKEN: ${{ secrets.DOCKERIO_TOKEN }} diff --git a/.gitignore b/.gitignore index e4064f4..791e511 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,32 @@ -# Ignore Xcode files +# This template file is stored at +# [GitHub Gist](https://gist.github.com/gautada/3a0a4a76d3c7e4539e71fc02c7f599ad) + +# XCode - Project files *.xcodeproj/ -volumes -.DS_STORE -manifest +# Desktop Services Store - Custom view preferences +.DS_Store + +# **Volume Folders** are used in development to set runtime data, usuaully +# this is private data and should almost **NEVER** be loaded into version +# control +**-volume/ + +# **Manifest Folder** is the k8s yaml files that deploy the container, usually +# this folder is sourced from a private repository and should not be public. +manifest/ + +# `.dockerignore` file allows you to specify a list of files or directories +# that Docker is to ignore during the build process. To create jusr +# symlink to this files `ln -s .gitignore .dockerignore` +.dockerignore + +.env +.flake8 +.hadolint.yaml +.htmlhintrc +.jscpd.json +.markdownlint.yaml +.pre-commit-config.yaml +.sqlfluff +.yamllint.yaml diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 0000000..9f5b72d --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1,3 @@ +# ShellCheck configuration +shell=sh +disable=SC3040,SC3020,SC3010,SC3010 diff --git a/pre-commit b/pre-commit new file mode 100755 index 0000000..04a5b61 --- /dev/null +++ b/pre-commit @@ -0,0 +1,110 @@ +#!/usr/bin/env bash +# shellcheck shell=bash +# ============================================================================= +# bin/pre-commit +# Syncs pre-commit config from gautada/cicd and runs pre-commit --all-files. +# +# Usage: +# curl -sSfL https://raw.githubusercontent.com/gautada/cicd/main/bin/pre-commit | bash +# curl -sSfL https://raw.githubusercontent.com/gautada/cicd/main/bin/pre-commit | bash -s -- --pull-only +# +# Options: +# --pull-only Pull config files from gautada/cicd only; skip install and run. +# +# Requirements: +# - Run from the root of a git checkout +# - pre-commit must be installed (pipx install --global pre-commit) +# - curl must be available +# ============================================================================= +set -euo pipefail + +CICD_RAW="https://raw.githubusercontent.com/gautada/cicd/main/templates/pre-commit" +PULL_ONLY=false + +# ---- Parse arguments -------------------------------------------------------- + +for arg in "$@"; do + case "$arg" in + --pull-only) PULL_ONLY=true ;; + *) echo "ERROR: Unknown argument: $arg" >&2; exit 1 ;; + esac +done + +# Config files to pull from gautada/cicd:/templates/pre-commit/ +CONFIG_FILES=( + ".flake8" + ".hadolint.yaml" + ".htmlhintrc" + ".jscpd.json" + ".markdownlint.yaml" + ".pre-commit-config.yaml" + ".shellcheckrc" + ".sqlfluff" + ".yamllint.yaml" +) + +# ---- Preflight checks ------------------------------------------------------- + +# Verify git repo +if ! git rev-parse --show-toplevel &>/dev/null; then + echo "ERROR: Not inside a git repository." >&2 + exit 1 +fi + +REPO_ROOT=$(git rev-parse --show-toplevel) +if [[ "$PWD" != "$REPO_ROOT" ]]; then + echo "ERROR: Run from the root of the git checkout." >&2 + echo " Expected: $REPO_ROOT" >&2 + exit 1 +fi + +# Verify curl is available +if ! command -v curl &>/dev/null; then + echo "ERROR: curl is required but not found." >&2 + exit 1 +fi + +# ---- Enforce canonical .gitignore ------------------------------------------- + +echo "==> Syncing canonical .gitignore template..." +curl -sSfL \ +https://raw.githubusercontent.com/gautada/cicd/refs/heads/main/templates/gitignore/.gitignore \ +-o .gitignore +echo "" + +# ---- Sync config files from gautada/cicd ------------------------------------ + +echo "==> Syncing pre-commit config from gautada/cicd/templates/pre-commit..." +for f in "${CONFIG_FILES[@]}"; do + echo " ↓ $f" + if ! curl -sSfL "$CICD_RAW/$f" -o "$f"; then + echo "ERROR: Failed to download $f from $CICD_RAW" >&2 + exit 1 + fi +done +echo "" + +# ---- Exit early if --pull-only ---------------------------------------------- + +if [[ "$PULL_ONLY" == true ]]; then + echo "==> Pull complete. Skipping install and run (--pull-only)." + exit 0 +fi + +# ---- Install/update hooks --------------------------------------------------- + +# Verify pre-commit is installed +if ! command -v pre-commit &>/dev/null; then + echo "ERROR: pre-commit is not installed." >&2 + echo " Install via: pipx install --global pre-commit" >&2 + exit 1 +fi + +echo "==> Installing pre-commit hooks..." +pre-commit install +echo "" + +# ---- Run linters ------------------------------------------------------------ + +echo "==> Running pre-commit on all files..." +pre-commit run --all-files