version: 2.1

orbs:
  win: circleci/windows@2.4.0
  prodsec: snyk/prodsec-orb@1

defaults: &defaults
  parameters:
    node_version:
      type: string
      default: ""
    go_version:
      type: string
      default: ""
  working_directory: ~/snyk-go-plugin

windows_defaults: &windows_defaults
  environment:
    npm_config_loglevel: silent
  executor:
    name: win/default

commands:
  install_node_npm_via_nvm:
    description: Install Node for when nvm is present
    parameters:
      node_version:
        type: string
        default: ""
    steps:
      - run:
          name: Install node@<< parameters.node_version >> (via nvm)
          command: nvm install << parameters.node_version >>
      - run:
          name: Use node@<< parameters.node_version >> (via nvm)
          command: nvm use << parameters.node_version >>
  install_deps:
    description: Install dependencies
    steps:
      - run:
          name: Install dependencies
          command: npm install
  install_node_npm_and_nvm:
    description: Install correct Node version
    parameters:
      node_version:
        type: string
        default: ""
    steps:
      - run:
          name: install node@<< parameters.node_version >>
          command: |
            cd ~
            curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash
            export NVM_DIR="$HOME/.nvm"
            [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
            [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
            nvm install << parameters.node_version >>
            echo 'export NVM_DIR="$HOME/.nvm"' >> $BASH_ENV
            echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> $BASH_ENV
            echo '[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"' >> $BASH_ENV
            echo 'nvm use << parameters.node_version >>' >> $BASH_ENV
  show_node_version:
    description: Log Node and npm version
    steps:
      - run:
          name: Node version
          command: node --version
      - run:
          name: NPM version
          command: npm --version
  install_go_windows:
    description: Install Go
    parameters:
      go_version:
        type: string
        default: ""
    steps:
      - run:
          name: Installing Go
          command: choco install golang --version << parameters.go_version >> --allow-downgrade

jobs:
  security-scans:
    resource_class: small
    <<: *defaults
    docker:
      - image: cimg/node:<< parameters.node_version >>
    steps:
      - checkout
      - install_deps
      - prodsec/security_scans:
          mode: auto
          open-source-additional-arguments: --exclude=test
          iac-scan: disabled

  lint:
    <<: *defaults
    docker:
      - image: cimg/node:<< parameters.node_version >>
    steps:
      - checkout
      - install_deps
      - show_node_version
      - run:
          name: Run lint
          command: npm run lint

  test-windows:
    <<: *defaults
    <<: *windows_defaults
    environment:
      Go: << parameters.go_version >>
    steps:
      - run: git config --global core.autocrlf false
      - checkout
      - install_node_npm_via_nvm:
          node_version: << parameters.node_version >>
      - install_go_windows:
          go_version: << parameters.go_version >>
      - show_node_version
      - install_deps
      - run:
          name: Run tests
          command: npm run test-windows

  test-unix:
    <<: *defaults
    docker:
      - image: cimg/go:<< parameters.go_version >>
    environment:
      GO_VERSION: << parameters.go_version >>
    steps:
      - checkout
      - install_node_npm_and_nvm:
          node_version: << parameters.node_version >>
      - show_node_version
      - install_deps
      - run:
          name: Run tests
          command: npm test

  release:
    <<: *defaults
    docker:
      - image: cimg/node:<< parameters.node_version >>
    resource_class: small
    steps:
      - checkout
      - install_deps
      - run:
          name: Publish to GitHub
          command: npx semantic-release

workflows:
  version: 2
  test_and_release:
    jobs:
      - prodsec/secrets-scan:
          name: Scan repository for secrets
          context:
            - snyk-bot-slack
          channel: snyk-vuln-alerts-sca
          filters:
            branches:
              ignore:
                - main
      - security-scans:
          name: Security Scans
          node_version: "20.19"
          context:
            - open_source-managed
            - nodejs-install
      - lint:
          name: Lint
          context: nodejs-install
          node_version: "20.19"
      - test-unix:
          name: Unix with node v<< matrix.node_version >>, go v<< matrix.go_version >>
          context: nodejs-install
          requires:
            - Lint
          matrix:
            parameters:
              node_version: ["20", "22", "24"]
              go_version: ["1.15", "1.16", "1.23", "1.24", "1.25"]
      - test-windows:
          name: Windows with node v<< matrix.node_version >>, go v<< matrix.go_version >>
          context: nodejs-install
          requires:
            - Lint
          matrix:
            parameters:
              node_version: ["20", "22", "24"]
              go_version: ["1.15", "1.16", "1.23", "1.24", "1.25"]

      # Release
      - release:
          name: Release
          context: nodejs-app-release
          node_version: "20.19"
          requires:
            - test-unix
            - test-windows
          filters:
            branches:
              only:
                - main
