name: Build Syncthing

on:
  pull_request:
  push:

env:
  # The go version to use for builds.
  GO_VERSION: "1.19.3"

  # Optimize compatibility on the slow archictures.
  GO386: softfloat
  GOARM: "5"
  GOMIPS: softfloat

  # Avoid hilarious amounts of obscuring log output when running tests.
  LOGGER_DISCARD: "1"

  # Our build metadata
  BUILD_USER: builder
  BUILD_HOST: github.syncthing.net

# A note on actions and third party code... The actions under actions/ (like
# `uses: actions/checkout`) are maintained by GitHub, and we need to trust
# GitHub to maintain their code and infrastructure or we're in deep shit in
# general. The same doesn't necessarily apply to other actions authors, so
# some care needs to be taken when adding steps, especially in the paths
# that lead up to code being packaged and signed.

jobs:

  #
  # Windows, quick build and test, runs always
  #

  build-windows:
    name: Build and test on Windows
    runs-on: windows-latest
    steps:
      - name: Set git to use LF
        # Without this, the checkout will happen with CRLF line endings,
        # which is fine for the source code but messes up tests that depend
        # on data on disk being as expected. Ideally, those tests should be
        # fixed, but not today.
        run: |
          git config --global core.autocrlf false
          git config --global core.eol lf

      - uses: actions/checkout@v3

      - uses: actions/setup-go@v3
        # `cache: true` gives us automatic caching of modules and build
        # cache, speeding up builds. The cache key is dependent on the Go
        # version and our go.sum contents.
        with:
          go-version: ${{ env.GO_VERSION }}
          cache: true

      - name: Build and test
        run: |
          go run build.go
          go run build.go test

  #
  # Windows, build signed packages
  #

  package-windows:
    name: Create packages for Windows
    runs-on: windows-latest
    # We only run this job for release pushes.
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/heads/release')
    # This is also enforced by the environment which contains the secrets.
    environment: signing
    needs:
      - build-windows
    steps:
      - name: Set git to use LF
        run: |
          git config --global core.autocrlf false
          git config --global core.eol lf

      - uses: actions/checkout@v3
        # `fetch-depth: 0` because we want to check out the entire repo
        # including tags and branches, not just the latest commit which
        # lacks version info.
        with:
          fetch-depth: 0

      - uses: actions/setup-go@v3
        with:
          go-version: ${{ env.GO_VERSION }}

      - uses: actions/cache@v3
        with:
          path: |
            ~\AppData\Local\go-build
            ~\go\pkg\mod
          key: ${{ runner.os }}-go-${{ env.GOVERSION }}-package-${{ hashFiles('**/go.sum') }}

      - name: Install dependencies
        run: |
          go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@v1.4.0

      - name: Create packages
        run: |
          go run build.go -goarch amd64 zip
          go run build.go -goarch arm zip
          go run build.go -goarch arm64 zip
          go run build.go -goarch 386 zip
        env:
          CODESIGN_SIGNTOOL: ${{ secrets.CODESIGN_SIGNTOOL }}
          CODESIGN_CERTIFICATE_BASE64: ${{ secrets.CODESIGN_CERTIFICATE_BASE64 }}
          CODESIGN_CERTIFICATE_PASSWORD: ${{ secrets.CODESIGN_CERTIFICATE_PASSWORD }}
          CODESIGN_TIMESTAMP_SERVER: ${{ secrets.CODESIGN_TIMESTAMP_SERVER }}

      - name: Archive artifacts
        uses: actions/upload-artifact@v3
        with:
          name: packages
          path: syncthing-windows-*.zip
