name: "Setup Golang environment"
description: "A reusable workflow that's used to set up the Go environment and cache."
inputs:
  go-version:
    description: "The version of Golang to set up"
    required: true
  key-prefix:
    description: "A prefix to use for the cache key, to separate cache entries from other workflows"
    required: false
  use-build-cache: 
    description: "Whether to use the build cache"
    required: false
    # Boolean values aren't supported in the workflow syntax, so we use a
    # string. To not confuse the value with true/false, we use 'yes' and 'no'.
    default: 'yes'

runs:
  using: "composite"

  steps:
    - name: setup go ${{ inputs.go-version }}
      uses: actions/setup-go@v5
      with:
        go-version: '${{ inputs.go-version }}'
        cache: 'false'

    # When we run go build or go test, the Go compiler calculates a signature
    # for each package based on the content of its `.go` source files, its
    # dependencies, and the compiler flags. It then checks the restored build
    # cache for an entry matching that exact signature to speed up the jobs.
    # - Cache Hit: If an entry exists (meaning the source files and
    #   dependencies haven't changed), it reuses the compiled artifact directly
    #   from the cache.  
    # - Cache Miss: If no entry exists (because we changed a line of code), it
    #   recompiles that specific package and stores the new result in the cache
    #   for the next time.
    - name: go cache
      if: ${{ inputs.use-build-cache == 'yes' }}
      uses: actions/cache@v4
      with:
        # In order:
        # * Module download cache
        # * Build cache (Linux)
        # * Build cache (Mac)
        # * Build cache (Windows)
        path: |
          ~/go/pkg/mod
          ~/.cache/go-build
          ~/Library/Caches/go-build
          ~\AppData\Local\go-build

        # The key is used to create and later look up the cache. It's made of
        # four parts:
        # - The base part is made from the OS name, Go version and a
        #   job-specified key prefix. Example: `linux-go-1.26.3-unit-test-`.
        #   It ensures that a job running on Linux with Go 1.26 only looks for
        #   caches from the same environment.
        # - The unique part is the `hashFiles('**/go.sum')`, which calculates a
        #   hash (a fingerprint) of the go.sum file. 
        key: ${{ runner.os }}-go-${{ inputs.go-version }}-${{ inputs.key-prefix }}-${{ hashFiles('**/go.sum') }}

        # The restore-keys provides a list of fallback keys. If no cache
        # matches the key exactly, the action will look for a cache where the
        # key starts with one of the restore-keys. The action searches the
        # restore-keys list in order and restores the most recently created
        # cache that matches the prefix. Once the job is done, a new cache is
        # created and saved using the new key. 
        restore-keys: |
          ${{ runner.os }}-go-${{ inputs.go-version }}-${{ inputs.key-prefix }}-

    # The complete, downloaded source code of all our dependencies (the
    # libraries lnd project imports). This prevents the go command from having
    # to re-download every dependency from the internet on every single job
    # run. It's like having a local library of all the third-party code lnd
    # needs.
    - name: go module cache
      if: ${{ inputs.use-build-cache == 'no' }}
      uses: actions/cache@v4
      with:
        # Just the module download cache.
        path: |
          ~/go/pkg/mod
        key: ${{ runner.os }}-go-${{ inputs.go-version }}-${{ inputs.key-prefix }}-no-build-cache-${{ hashFiles('**/go.sum') }}
        restore-keys: |
          ${{ runner.os }}-go-${{ inputs.go-version }}-${{ inputs.key-prefix }}-no-build-cache-

    - name: set GOPATH
      shell: bash
      run: |
        echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
