diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index 97c3d1b0..9566651a 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -12,6 +12,44 @@ concurrency: cancel-in-progress: true jobs: + archlinux: + name: workstation (archlinux) + runs-on: ubuntu-latest + container: + image: greyltc/archlinux-aur:yay + options: --user root + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Test Arch dependencies + shell: bash + run: >- + sudo -E -u ab -D~ bash -c ' + cd $GITHUB_WORKSPACE; + yay -Syu --needed --noconfirm --noprogressbar go-task; + go-task workstation:arch + ' + + generic-linux: + name: workstation (generic-linux) + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Homebrew + id: setup-homebrew + uses: Homebrew/actions/setup-homebrew@master + + - name: Setup Workflow Tools + shell: bash + run: brew install go-task + + - name: Run Workstation Generic linux tasks + shell: bash + run: task workstation:generic-linux + configure: if: ${{ github.repository == 'onedr0p/cluster-template' }} name: configure @@ -33,7 +71,7 @@ jobs: uses: actions/setup-python@v5 id: setup-python with: - python-version: "3.11" # minimum supported version + python-version: "3.11" - name: Cache homebrew packages if: ${{ github.event_name == 'pull_request' }} diff --git a/.taskfiles/bootstrap/Taskfile.yaml b/.taskfiles/bootstrap/Taskfile.yaml index ffa726fb..f176a43c 100644 --- a/.taskfiles/bootstrap/Taskfile.yaml +++ b/.taskfiles/bootstrap/Taskfile.yaml @@ -76,14 +76,30 @@ tasks: status: - test -f {{.SOPS_AGE_KEY_FILE}} - encrypt: - desc: Encrypt all Kubernetes SOPS secrets - cmd: | - find "{{.KUBERNETES_DIR}}" -type f -name "*.sops.*" | while read -r file; do - if sops filestatus "${file}" | jq --exit-status ".encrypted == false" &>/dev/null; then - sops --encrypt --in-place "${file}" + template: + internal: true + cmd: '{{.VIRTUAL_ENV}}/bin/makejinja' + preconditions: + - msg: Missing virtual environment + sh: test -d {{.VIRTUAL_ENV}} + - msg: Missing Makejinja config file + sh: test -f {{.MAKEJINJA_CONFIG_FILE}} + - msg: Missing Makejinja plugin file + sh: test -f {{.BOOTSTRAP_DIR}}/scripts/plugin.py + - msg: Missing bootstrap config file + sh: test -f {{.BOOTSTRAP_CONFIG_FILE}} + + secrets: + internal: true + cmds: + - for: { var: SECRET_FILES } + cmd: | + if sops filestatus "{{.ITEM}}" | jq --exit-status ".encrypted == false" &>/dev/null; then + sops --encrypt --in-place "{{.ITEM}}" fi - done + vars: + SECRET_FILES: + sh: find "{{.KUBERNETES_DIR}}" -type f -name "*.sops.*" preconditions: - msg: Missing Sops config file sh: test -f {{.SOPS_CONFIG_FILE}} diff --git a/.taskfiles/workstation/Archfile b/.taskfiles/workstation/Archfile index b1ad3160..40ebdbc9 100644 --- a/.taskfiles/workstation/Archfile +++ b/.taskfiles/workstation/Archfile @@ -10,6 +10,7 @@ jq kubeconform kubectl-bin kustomize +minijinja moreutils sops stern-bin diff --git a/.taskfiles/workstation/Brewfile b/.taskfiles/workstation/Brewfile index 6442f0c1..65f69bf5 100644 --- a/.taskfiles/workstation/Brewfile +++ b/.taskfiles/workstation/Brewfile @@ -12,6 +12,7 @@ brew "jq" brew "kubeconform" brew "kubernetes-cli" brew "kustomize" +brew "minijinja-cli" brew "moreutils" brew "siderolabs/tap/talosctl" brew "sops" diff --git a/.taskfiles/workstation/Taskfile.yaml b/.taskfiles/workstation/Taskfile.yaml index 666c182a..d3357d6e 100644 --- a/.taskfiles/workstation/Taskfile.yaml +++ b/.taskfiles/workstation/Taskfile.yaml @@ -9,10 +9,10 @@ tasks: cmd: '{{.PKGMGR}} -Syu --needed --noconfirm --noprogressbar $(cat {{.ROOT_DIR}}/.taskfiles/workstation/Archfile | xargs)' vars: PKGMGR: - sh: command -v yay || command -v paru + sh: command -v paru || command -v yay preconditions: - - msg: Missing yay or paru - sh: command -v brew &>/dev/null || command -v paru &>/dev/null + - msg: Missing paru or yay + sh: command -v paru &>/dev/null || command -v yay &>/dev/null - msg: Missing Archfile sh: test -f {{.ROOT_DIR}}/.taskfiles/workstation/Archfile @@ -46,24 +46,32 @@ tasks: platforms: ['linux/amd64', 'linux/arm64'] cmds: - for: - - budimanjojo/talhelper?as=talhelper&type=script - - cloudflare/cloudflared?as=cloudflared&type=script - - FiloSottile/age?as=age&type=script - - fluxcd/flux2?as=flux&type=script - - getsops/sops?as=sops&type=script - - helmfile/helmfile?as=helmfile&type=script - - jqlang/jq?as=jq&type=script - - kubernetes-sigs/kustomize?as=kustomize&type=script - - siderolabs/talos?as=talosctl&type=script - - yannh/kubeconform?as=kubeconform&type=script - - mikefarah/yq?as=yq&type=script - cmd: curl -fsSL "https://i.jpillora.com/{{.ITEM}}" | bash - - cmd: curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" + - budimanjojo/talhelper?as=talhelper + - cloudflare/cloudflared?as=cloudflared + - FiloSottile/age?as=age + - fluxcd/flux2?as=flux + - helmfile/helmfile?as=helmfile + - jqlang/jq?as=jq + - kubernetes-sigs/kustomize?as=kustomize + - mikefarah/yq?as=yq + - siderolabs/talos?as=talosctl + - yannh/kubeconform?as=kubeconform + cmd: curl -fsSL "https://i.jpillora.com/{{.ITEM}}&type=script" | bash + - cmd: | + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"; + curl -sSfL -o sops https://github.com/getsops/sops/releases/latest/download/sops-v3.9.1.linux.amd64 platforms: ['linux/amd64'] - - cmd: curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl" + - cmd: | + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl"; + curl -sSfL -o sops https://github.com/getsops/sops/releases/latest/download/sops-v3.9.1.linux.arm64 platforms: ['linux/arm64'] - - cmd: chmod +x kubectl - - cmd: curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | USE_SUDO="false" HELM_INSTALL_DIR="." bash + - cmd: chmod +x kubectl sops + - cmd: curl -sSfL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash + - cmd: curl -sSfL https://github.com/mitsuhiko/minijinja/releases/latest/download/minijinja-cli-installer.sh | bash + env: + MINIJINJA_CLI_INSTALL_DIR: '.' + HELM_INSTALL_DIR: '.' + USE_SUDO: 'false' venv: desc: Set up virtual environment diff --git a/Taskfile.yaml b/Taskfile.yaml index 4f3736c1..10090c65 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -2,6 +2,9 @@ # yaml-language-server: $schema=https://taskfile.dev/schema.json version: '3' +set: [pipefail] +shopt: [globstar] + vars: BOOTSTRAP_DIR: '{{.ROOT_DIR}}/bootstrap' KUBERNETES_DIR: '{{.ROOT_DIR}}/kubernetes' @@ -31,44 +34,19 @@ tasks: init: desc: Initialize configuration files - cmds: - - cp {{if eq OS "darwin"}}-n{{else}}--update=none{{end}} {{.BOOTSTRAP_CONFIG_FILE | replace ".yaml" ".sample.yaml"}} {{.BOOTSTRAP_CONFIG_FILE}} - - echo "=== Configuration file copied ===" - - echo "Proceed with updating the configuration files..." - - echo "{{.BOOTSTRAP_CONFIG_FILE}}" + cmd: cp {{.BOOTSTRAP_CONFIG_FILE | replace ".yaml" ".sample.yaml"}} {{.BOOTSTRAP_CONFIG_FILE}} status: - test -f {{.BOOTSTRAP_CONFIG_FILE}} - silent: true configure: - desc: Configure repository from bootstrap vars + desc: Render and validate configuration files prompt: Any conflicting config in the kubernetes directory will be overwritten... continue? - deps: ['workstation:direnv', 'workstation:venv', 'bootstrap:age-keygen', 'init'] - cmds: - - task: template - - task: bootstrap:encrypt - - task: validate - - template: - internal: true - cmd: '{{.VIRTUAL_ENV}}/bin/makejinja' - preconditions: - - msg: Missing virtual environment - sh: test -d {{.VIRTUAL_ENV}} - - msg: Missing Makejinja config file - sh: test -f {{.MAKEJINJA_CONFIG_FILE}} - - msg: Missing Makejinja plugin file - sh: test -f {{.BOOTSTRAP_DIR}}/scripts/plugin.py - - msg: Missing bootstrap config file - sh: test -f {{.BOOTSTRAP_CONFIG_FILE}} - - validate: - internal: true + deps: + - init + - bootstrap:age-keygen + - workstation:direnv + - workstation:venv cmds: + - task: bootstrap:template + - task: bootstrap:secrets - task: kubernetes:kubeconform - - echo "=== Done rendering and validating YAML ===" - - '{{if eq .HOME_SOPS_AGE_KEY_FILE_EXISTS "true"}}echo "WARNING: SOPS Age key found in home directory, this may cause conflicts."{{end}}' - vars: - HOME_SOPS_AGE_KEY_FILE_EXISTS: - sh: test -f ~/.config/sops/age/keys.txt && echo true || echo false - silent: true