version: 2.1

orbs:
  codecov: codecov/codecov@3

executors:
  node:
    docker:
      - image: node:22-slim
  golangci-lint:
    docker:
      - image: golangci/golangci-lint:v1.64
  golang-previous:
    docker:
      - image: golang:1.23
  golang-latest:
    docker:
      - image: golang:1.24

jobs:
  lint-markdown:
    executor: node
    steps:
      - checkout
      - run:
          name: Install markdownlint
          command: npm install -g markdownlint-cli
      - run:
          name: Check for Lint
          command: markdownlint .

  lint-source:
    executor: golangci-lint
    steps:
      - checkout
      - run:
          name: Check for Lint
          command: golangci-lint run

  check-go-mod:
    executor: golang-latest
    steps:
      - checkout
      - run:
          name: Check Module Tidiness
          command: go mod tidy -diff

  check-test-corpus:
    executor: golang-latest
    steps:
      - checkout
      - run:
          name: Generate Test Corpus
          command: pushd test/images/ && go run ./gen_sifs.go && popd
      - run:
          name: Check Test Corpus Tidiness
          command: git diff --exit-code --

  check-vulnerabilities:
    executor: golang-latest
    steps:
      - checkout
      - run:
          name: Install govulncheck
          command: go install golang.org/x/vuln/cmd/govulncheck@latest
      - run:
          name: Check for vulnerabilities
          command: govulncheck ./...

  build-source:
    parameters:
      e:
        type: executor
    executor: << parameters.e >>
    steps:
      - checkout
      - run:
          name: Build Source
          command: go build ./...

  unit-test:
    parameters:
      e:
        type: executor
    executor: << parameters.e >>
    steps:
      - checkout
      - run:
          name: Run Unit Tests
          command: go test -coverprofile cover.out -race ./...
      - codecov/upload:
          file: cover.out

  release-test:
    executor: golang-latest
    steps:
      - checkout
      - run:
          name: Install syft
          command: curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
      - run:
          name: Check Configuration
          command: curl -sSfL https://goreleaser.com/static/run | bash -s -- check
      - run:
          name: Test Release
          command: curl -sSfL https://goreleaser.com/static/run | bash -s -- --snapshot --skip=publish

  publish-release:
    executor: golang-latest
    steps:
      - checkout
      - run:
          name: Install syft
          command: curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
      - run:
          name: Publish Release
          command: curl -sSfL https://goreleaser.com/static/run | bash

workflows:
  version: 2

  build-and-test:
    jobs:
      - lint-markdown
      - lint-source
      - check-go-mod
      - check-test-corpus
      - check-vulnerabilities
      - build-source:
          matrix:
            parameters:
              e: ["golang-previous", "golang-latest"]
      - unit-test:
          matrix:
            parameters:
              e: ["golang-previous", "golang-latest"]
      - release-test

  tagged-release:
    jobs:
      - publish-release:
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /v[0-9]+(\.[0-9]+)*(-.*)*/
          context: github-release
