diff --git a/.github/workflows/build-syncthing.yaml b/.github/workflows/build-syncthing.yaml index dd8b12640..fb8d94087 100644 --- a/.github/workflows/build-syncthing.yaml +++ b/.github/workflows/build-syncthing.yaml @@ -127,6 +127,7 @@ jobs: - package-cross - package-source - package-debian + - package-windows - govulncheck steps: - uses: actions/checkout@v4 @@ -137,8 +138,6 @@ jobs: package-windows: name: Package for Windows - if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && (github.ref == 'refs/heads/release' || startsWith(github.ref, 'refs/heads/release-') || startsWith(github.ref, 'refs/tags/v')) - environment: release runs-on: windows-latest steps: - name: Set git to use LF @@ -188,16 +187,65 @@ jobs: } env: CGO_ENABLED: "0" - 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@v4 + with: + name: unsigned-packages-windows + path: "*.zip" + + codesign-windows: + name: Codesign for Windows + if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && (github.ref == 'refs/heads/release' || startsWith(github.ref, 'refs/heads/release-') || startsWith(github.ref, 'refs/tags/v')) + environment: release + runs-on: windows-latest + needs: + - package-windows + steps: + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: unsigned-packages-windows + path: packages + + - name: Extract packages + working-directory: packages + run: | + $files = Get-ChildItem "." -Filter *.zip + foreach ($file in $files) { + 7z x $file.Name + } + + - name: Sign files with Trusted Signing + uses: azure/trusted-signing-action@v0.5.1 + with: + azure-tenant-id: ${{ secrets.AZURE_TRUSTED_SIGNING_TENANT_ID }} + azure-client-id: ${{ secrets.AZURE_TRUSTED_SIGNING_CLIENT_ID }} + azure-client-secret: ${{ secrets.AZURE_TRUSTED_SIGNING_CLIENT_SECRET }} + endpoint: ${{ secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} + trusted-signing-account-name: ${{ secrets.AZURE_TRUSTED_SIGNING_ACCOUNT }} + certificate-profile-name: ${{ secrets.AZURE_TRUSTED_SIGNING_PROFILE }} + files-folder: ${{ github.workspace }}\packages + files-folder-filter: exe + files-folder-recurse: true + file-digest: SHA256 + timestamp-rfc3161: http://timestamp.acs.microsoft.com + timestamp-digest: SHA256 + + - name: Repackage packages + working-directory: packages + run: | + $files = Get-ChildItem "." -Filter *.zip + foreach ($file in $files) { + Remove-Item $file.Name + 7z a -tzip $file.Name $file.BaseName + } - name: Archive artifacts uses: actions/upload-artifact@v4 with: name: packages-windows - path: "*.zip" + path: "packages/*.zip" # # Linux @@ -502,7 +550,7 @@ jobs: if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && (github.ref == 'refs/heads/release' || startsWith(github.ref, 'refs/heads/release-') || startsWith(github.ref, 'refs/tags/v')) environment: release needs: - - package-windows + - codesign-windows - package-linux - package-macos - package-cross diff --git a/build.go b/build.go index f7c106313..08d81414e 100644 --- a/build.go +++ b/build.go @@ -15,7 +15,6 @@ import ( "bytes" "compress/flate" "compress/gzip" - "encoding/base64" "encoding/json" "errors" "flag" @@ -1345,10 +1344,7 @@ func zipFile(out string, files []archiveFile) { } func codesign(target target) { - switch goos { - case "windows": - windowsCodesign(target.BinaryName()) - case "darwin": + if goos == "darwin" { macosCodesign(target.BinaryName()) } } @@ -1372,70 +1368,6 @@ func macosCodesign(file string) { } } -func windowsCodesign(file string) { - st := "signtool.exe" - - if path := os.Getenv("CODESIGN_SIGNTOOL"); path != "" { - st = path - } - - for i, algo := range []string{"sha1", "sha256"} { - args := []string{"sign", "/fd", algo} - if f := os.Getenv("CODESIGN_CERTIFICATE_FILE"); f != "" { - args = append(args, "/f", f) - } else if b := os.Getenv("CODESIGN_CERTIFICATE_BASE64"); b != "" { - // Decode the PFX certificate from base64. - bs, err := base64.RawStdEncoding.DecodeString(b) - if err != nil { - log.Println("Codesign: signing failed: decoding base64:", err) - return - } - - // Write it to a temporary file - f, err := os.CreateTemp("", "codesign-*.pfx") - if err != nil { - log.Println("Codesign: signing failed: creating temp file:", err) - return - } - _ = f.Chmod(0o600) // best effort remove other users' access - defer os.Remove(f.Name()) - if _, err := f.Write(bs); err != nil { - log.Println("Codesign: signing failed: writing temp file:", err) - return - } - if err := f.Close(); err != nil { - log.Println("Codesign: signing failed: closing temp file:", err) - return - } - - // Use that when signing - args = append(args, "/f", f.Name()) - } - if p := os.Getenv("CODESIGN_CERTIFICATE_PASSWORD"); p != "" { - args = append(args, "/p", p) - } - if tr := os.Getenv("CODESIGN_TIMESTAMP_SERVER"); tr != "" { - switch algo { - case "sha256": - args = append(args, "/tr", tr, "/td", algo) - default: - args = append(args, "/t", tr) - } - } - if i > 0 { - args = append(args, "/as") - } - args = append(args, file) - - bs, err := runError(st, args...) - if err != nil { - log.Printf("Codesign: signing failed: %v: %s", err, string(bs)) - return - } - log.Println("Codesign: successfully signed", file, "using", algo) - } -} - func metalint() { lazyRebuildAssets() runPrint(goCmd, "test", "-run", "Metalint", "./meta")