Build, sign, and publish release binaries

This PR adds a workflow to build releases:

- The builds are signed on Windows.
- The builds are organized into a `build` folder, to make things easier to understand and debug.
- The `build` folder is uploaded as artifacts on Actions, in one collective `build.zip`.
- If a tag was pushed, the build release files are individually uploaded as assets to the releases page:
  - Compare [`smimesign-staging@v1.1.0-rc1`](https://github.com/github/smimesign-staging/releases/tag/v1.1.0-rc1) to [`smimesign@v0.0.13`](https://github.com/github/smimesign/releases/tag/v0.0.13) and note that I've managed to keep fairly similar names and formats (e.g. `.tgz` for macOS).
- Tags starting with `v` are automatically marked as releases, so the latest release will always show up on the side of https://github.com/github/smimesign (if your window is wide enough).
- The version string is consistently embedded using `-ldflags` for all builds. I've directly checked that this works, using `smimesign --version` on amd64, the installer, and macOS.
- We now build using Go 1.17.

This PR does not add code signing for macOS, and doesn't add a build for Apple Silicon. We [recommend using Homebrew](https://github.com/github/smimesign#macos) to install `smimesign` on macOS, which works the same without signing and already builds for Apple Silicon.
This commit is contained in:
Lucas Garron 2021-09-22 20:10:46 -07:00
Родитель e227155756
Коммит c6ad9bc79c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B6FDB8D2256D0D19
9 изменённых файлов: 155 добавлений и 144 удалений

Просмотреть файл

@ -1,83 +0,0 @@
skip_branch_with_pr: true
version: "{build}-{branch}"
os: "Visual Studio 2015"
clone_folder: C:\gopath\src\github.com\github\smimesign
environment:
pfx_password:
secure: WfQzoLeQ6dGF2NnDKhZX6ai/k5s+qWyWLdIZoAjPineepfZeXovgrB2bmOtZfO2d
init:
# Always build with CGO
- set CGO_ENABLED=1
# Paths and Go environment
- set GOPATH=c:\gopath
- set GOROOT=c:\go112
- set PATH=%GOROOT%\bin;%GOPATH%\bin;C:\msys64\usr\bin;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin;%PATH%
- set PATH_WAS=%PATH%
# appveyor sets GO111MODULE=auto, which we don't want
- set GO111MODULE=on
install:
- go get github.com/josephspurrier/goversioninfo/cmd/goversioninfo
- cinst InnoSetup -y
before_build:
# Figure out version numbers
- git describe --tags > version
- FOR /F "delims=v tokens=1" %%G IN (version) DO set GIT_VERSION=%%G
- FOR /F "delims=v.- tokens=1" %%G IN (version) DO set VERSION_MAJOR=%%G
- FOR /F "delims=v.- tokens=2" %%G IN (version) DO set VERSION_MINOR=%%G
- FOR /F "delims=v.- tokens=3" %%G IN (version) DO set VERSION_PATCH=%%G
# Generate resource.syso
- go generate
build_script:
# Build x64 binary
- set GOARCH=amd64
- set PATH=C:\msys64\MINGW64\bin;%PATH_WAS%
- go build -o smimesign-amd64.exe -ldflags "-X main.versionString=%GIT_VERSION%" .
# Build x86 binary
- set GOARCH=386
- set PATH=C:\msys64\MINGW32\bin;%PATH_WAS%
- go build -o smimesign-386.exe -ldflags "-X main.versionString=%GIT_VERSION%" .
after_build:
# Sign binaries
- if "%pfx_password%" NEQ "" (signtool.exe sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /p %pfx_password% /f windows-installer\codesign.pfx smimesign-amd64.exe)
- if "%pfx_password%" NEQ "" (signtool.exe sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /p %pfx_password% /f windows-installer\codesign.pfx smimesign-386.exe)
# Build zip archives
- copy smimesign-amd64.exe smimesign.exe
- 7z a smimesign-windows-amd64-%GIT_VERSION%.zip smimesign.exe
- del smimesign.exe
- copy smimesign-386.exe smimesign.exe
- 7z a smimesign-windows-386-%GIT_VERSION%.zip smimesign.exe
- del smimesign.exe
# Build installer
- iscc windows-installer/inno-setup-smimesign-installer.iss
# Sign installer — AppVeyor's "secure variables" aren't included in PR builds,
# so we skip this step if the PFX password is missing.
- if "%pfx_password%" NEQ "" (signtool.exe sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /p %pfx_password% /f windows-installer\codesign.pfx smimesign-windows-*.exe)
test_script:
- go test -v ./...
artifacts:
- path: smimesign-windows-*.exe
- path: smimesign-windows-*.zip
deploy:
tag: v$(GIT_VERSION)
release: v$(GIT_VERSION)
description: v$(GIT_VERSION)
provider: GitHub
auth_token:
secure: sEpJVeD+tAT8soMS72SeGXEv1UVg7gG1ySy8rEfAO1T5HCaxD3jE6YoGmYOvKcbx
artifact: /smimesign-windows-.*\.(exe|zip)/
draft: false
prerelease: false
on:
branch: main
appveyor_repo_tag: true

136
.github/workflows/build-binaries.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,136 @@
on: [push, pull_request]
name: Build binaries
jobs:
build-macos:
strategy:
matrix:
go-version: ["1.17"]
os: [macos-latest]
runs-on: ${{ matrix.os }}
env:
CGO_ENABLED: 1
steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
with:
# `fetch-depth: 0` gets us all tags.
fetch-depth: 0
- name: Calculate git version and add it to the environment
shell: bash
# We have to `$GITHUB_ENV` to create env vars that can be used in future steps (in particular, as part of download file names).
# https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#environment-files
# https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/
run: |
echo "GIT_VERSION=$(git describe --tags)" >> $GITHUB_ENV
- name: Build macos binary
run: |
go build -o build/macos/smimesign -ldflags "-X main.versionString=${{ env.GIT_VERSION }}" .
- name: Tar the macOS binary
run: |
# We cd so that the binary ends up in the top level of the tar.
cd build/macos && tar -czvf smimesign-macos-${{ env.GIT_VERSION }}.tgz smimesign
- name: Upload build folder to the action
uses: actions/upload-artifact@v2
with:
# Note: this artifact is shared across jobs:
# https://github.com/actions/upload-artifact#uploading-to-the-same-artifact
name: build
path: build/
- name: Upload macOS files to the release
# Pinned hash from https://github.com/softprops/action-gh-release/releases/tag/v0.1.12
uses: softprops/action-gh-release@2d72d869af3bf23602f9593a1e3fd739b80ac1eb
if: startsWith(github.ref, 'refs/tags/v')
with:
files: |
build/macOS/smimesign-macos-${{ env.GIT_VERSION }}.tgz
build-windows:
strategy:
matrix:
go-version: ["1.17"]
os: [windows-latest]
runs-on: ${{ matrix.os }}
env:
CGO_ENABLED: 1
steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
with:
# `fetch-depth: 0` gets us all tags.
fetch-depth: 0
- name: Calculate git version and add it to the environment
shell: bash
# We have to use this format to create env vars that can be used in future steps (in particular, as part of download file names).
# https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#environment-files
# https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/
run: |
echo "GIT_VERSION=$(git describe --tags)" >> $GITHUB_ENV
- name: Calculate bare git version and add it to the environment
# This is for InnoSetup
shell: bash
run: |
if [[ "${GIT_VERSION}" =~ ^v([[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+)(-[A-za-z0-9-]*)? ]]
then
echo "BARE_GIT_VERSION=${BASH_REMATCH[1]}" >> $GITHUB_ENV
else
echo "Could not calculate the bare git version (e.g. `v1.1.0-rc1-28-g8a54734` -> `1.1.0`) for: ${GIT_VERSION}"
exit 1
fi
- name: Build amd64
shell: bash
run: |
GOARCH=amd64 go build -o "build/amd64/smimesign.exe" -ldflags "-X main.versionString=${{ env.GIT_VERSION }}"
- name: Switch MinGW to x86
# Pinned hash from https://github.com/egor-tensin/setup-mingw/releases/tag/v2
uses: egor-tensin/setup-mingw@f3c5d799aadf8fa230ac67a422b01dd085bbc96b
with:
platform: x86
- name: Build 386
shell: bash
run: |
GOARCH=386 go build -o "build/386/smimesign.exe" -ldflags "-X main.versionString=${{ env.GIT_VERSION }}" .
- name: Sign amd64 and 386
if: startsWith(github.ref, 'refs/tags/v')
run: |
.\windows-installer\signtool.exe sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /p ${{ secrets.PFX_PASSWORD }} /f windows-installer\codesign.pfx build/amd64/smimesign.exe
.\windows-installer\signtool.exe sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /p ${{ secrets.PFX_PASSWORD }} /f windows-installer\codesign.pfx build/386/smimesign.exe
- name: Create installer
shell: bash
run: |
GIT_VERSION=${{ env.GIT_VERSION }} BARE_GIT_VERSION=${{ env.BARE_GIT_VERSION }} iscc windows-installer/inno-setup-smimesign-installer.iss
- name: Sign installer
if: startsWith(github.ref, 'refs/tags/v')
run: |
.\windows-installer\signtool.exe sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /p ${{ secrets.PFX_PASSWORD }} /f windows-installer\codesign.pfx build\installer\smimesign-windows-*.exe
- name: Create zips for release upload
run: |
Compress-Archive -Path build\amd64\smimesign.exe -DestinationPath build\amd64\smimesign.zip
Compress-Archive -Path build\386\smimesign.exe -DestinationPath build\386\smimesign.zip
- name: Rename zips for release upload
shell: bash
run: |
mv build/amd64/smimesign.zip build/amd64/smimesign-windows-amd64-${{ env.GIT_VERSION }}.zip
mv build/386/smimesign.zip build/386/smimesign-windows-386-${{ env.GIT_VERSION }}.zip
- name: Upload build folder to the action
uses: actions/upload-artifact@v2
with:
# Note: this artifact is shared across jobs:
# https://github.com/actions/upload-artifact#uploading-to-the-same-artifact
name: build
path: build/
- name: Upload Windows files to the release
# Pinned hash from https://github.com/softprops/action-gh-release/releases/tag/v0.1.12
uses: softprops/action-gh-release@2d72d869af3bf23602f9593a1e3fd739b80ac1eb
if: startsWith(github.ref, 'refs/tags/v')
with:
files: |
build/amd64/smimesign-windows-amd64-${{ env.GIT_VERSION }}.zip
build/386/smimesign-windows-386-${{ env.GIT_VERSION }}.zip
build/installer/smimesign-windows-*.exe

10
.github/workflows/test-macos-go.yml поставляемый
Просмотреть файл

@ -7,6 +7,8 @@ jobs:
go-version: ["1.14", "1.x"] go-version: ["1.14", "1.x"]
os: [macos-latest] os: [macos-latest]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
env:
CGO_ENABLED: 1
steps: steps:
- name: Install Go - name: Install Go
uses: actions/setup-go@v2 uses: actions/setup-go@v2
@ -14,10 +16,6 @@ jobs:
go-version: ${{ matrix.go-version }} go-version: ${{ matrix.go-version }}
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Setup Environment
run: |
echo GIT_VERSION=$(git describe --tags) >> $GITHUB_ENV
- name: Test - name: Test
run: GO111MODULE=on go test -v ./... run: |
go test -v ./...

13
.github/workflows/test-windows-go.yml поставляемый
Просмотреть файл

@ -7,6 +7,8 @@ jobs:
go-version: ["1.14", "1.x"] go-version: ["1.14", "1.x"]
os: [windows-latest] os: [windows-latest]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
env:
CGO_ENABLED: 1
steps: steps:
- name: Install Go - name: Install Go
uses: actions/setup-go@v2 uses: actions/setup-go@v2
@ -14,13 +16,6 @@ jobs:
go-version: ${{ matrix.go-version }} go-version: ${{ matrix.go-version }}
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Setup Environment
run: |
echo GIT_VERSION=$(git describe --tags) >> $GITHUB_ENV
- name: Test - name: Test
env: run: |
CGO_ENABLED: 1 go test -v ./...
GO111MODULE: "on"
run: go test -v ./...

4
.gitignore поставляемый
Просмотреть файл

@ -1,3 +1 @@
smimesign /build
smimesign.exe
resource.syso

Просмотреть файл

@ -1,30 +0,0 @@
os: osx
language: go
go:
- 1.12.x
- 1.x
- master
git:
depth: false
install: ''
script:
- GIT_VERSION=$(git describe --tags)
- GO111MODULE=on go build -o smimesign -ldflags "-X main.versionString=$GIT_VERSION" .
- tar czf smimesign-$GIT_VERSION-macos.tgz smimesign
- GO111MODULE=on go test -v ./...
deploy:
name: $GIT_VERSION
provider: releases
skip_cleanup: true
file: smimesign-$GIT_VERSION-macos.tgz
on:
tags: true
go: 1.x
api_key:
secure: ETRXbCU4rdP7SE9ULTN9VqfzTiInav5LXjfvmuUo3GJTu1TmKOgsvo87aSK+ns/AkGiWXNXrHhwgfnC73jdT7o562bE/r3TG1QaBtiEcf5jn8d9HI5XXbCH1b2+yl6lpkhilDa7MxGO8d2C51gzvUyL3Zbnfqxbrploe4w3ZwnHJRObS55OQu8Ooyf1HaeK4hvoazT0Ww5Hg2joLYnB2Z9U7ucOdmQkQ8cnRZiyoSoczTnnY7JF0o83Ei5atMuDLFYR1zzKrYjBUs0Awl8tSK6t+I/dQgVYAX2QJrfkoJrXbQu5ytASvo3VUYSJkZHnGKvWi+dUbSOV+DB+uqQYYE8Ix+fOENnicuUFJuLXIWUiGJ0X3zZ2+2AeN0uHxlO1S3bJp5x8Vt5Q2uYaFQagNvkn7s9HSIy9rf6UR80a9brUiyqCQlLJcu3x+b5/KyRVyvlKupG5yD9PCv9wO1gjQts2mbCGjRQQ62Ub+PpiGQY+59jz3AjOtqrWaNkjSpAVVHkuj8Rl4X6OblCQOXskMnLk8gl2OLO7uhLlEcOUJiCbrqHZ75V1LTUa/TOx+xhQIOjTFgvbUTPQHz7eSuNVD3GuJCHMDzzUCVFaXcgX+dsDMbsqugubBRelrmCv+TS4AurCU8M3zGsZPYZV3uKt9zKIriZQ31b2hltGimRpDFDE=

Просмотреть файл

Просмотреть файл

@ -1,21 +1,18 @@
#define MyAppName "smimesign" #define MyAppName "smimesign"
#define PathToX86Binary "../smimesign-386.exe" #define MyGitVersion GetEnv("GIT_VERSION")
#define MyBareGitVersion GetEnv("BARE_GIT_VERSION")
#define PathToX86Binary "../build/386/smimesign.exe"
#ifnexist PathToX86Binary #ifnexist PathToX86Binary
#pragma error PathToX86Binary + " does not exist, please build it first." #pragma error PathToX86Binary + " does not exist, please build it first."
#endif #endif
#define PathToX64Binary "../smimesign-amd64.exe" #define PathToX64Binary "../build/amd64/smimesign.exe"
#ifnexist PathToX64Binary #ifnexist PathToX64Binary
#pragma error PathToX64Binary + " does not exist, please build it first." #pragma error PathToX64Binary + " does not exist, please build it first."
#endif #endif
; Arbitrarily choose the x86 executable here as both have the version embedded.
#define MyVersionInfoVersion GetFileVersion(PathToX86Binary)
; Misuse RemoveFileExt to strip the 4th patch-level version number.
#define MyAppVersion RemoveFileExt(MyVersionInfoVersion)
#define MyAppPublisher "GitHub, Inc." #define MyAppPublisher "GitHub, Inc."
#define MyAppURL "https://github.com/github/smimesign" #define MyAppURL "https://github.com/github/smimesign"
#define MyAppFilePrefix "smimesign-windows" #define MyAppFilePrefix "smimesign-windows"
@ -31,7 +28,7 @@ AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL} AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL} AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL} AppUpdatesURL={#MyAppURL}
AppVersion={#MyAppVersion} AppVerName={#MyBareGitVersion}
ArchitecturesInstallIn64BitMode=x64 ArchitecturesInstallIn64BitMode=x64
ChangesEnvironment=yes ChangesEnvironment=yes
Compression=lzma Compression=lzma
@ -39,12 +36,12 @@ DefaultDirName={code:GetDefaultDirName}
DirExistsWarning=no DirExistsWarning=no
DisableReadyPage=True DisableReadyPage=True
LicenseFile=..\LICENSE.md LicenseFile=..\LICENSE.md
OutputBaseFilename={#MyAppFilePrefix}-{#MyAppVersion} OutputBaseFilename={#MyAppFilePrefix}-{#MyGitVersion}
OutputDir=..\ OutputDir=..\build\installer\
PrivilegesRequired=none PrivilegesRequired=none
SolidCompression=yes SolidCompression=yes
UsePreviousAppDir=no UsePreviousAppDir=no
VersionInfoVersion={#MyVersionInfoVersion} VersionInfoVersion={#MyBareGitVersion}
[Languages] [Languages]
Name: "english"; MessagesFile: "compiler:Default.isl" Name: "english"; MessagesFile: "compiler:Default.isl"
@ -60,7 +57,7 @@ Root: HKCU; Subkey: "Environment"; ValueType: expandsz; ValueName: "Path"; Value
[Code] [Code]
function GetDefaultDirName(Dummy: string): string; function GetDefaultDirName(Dummy: string): string;
begin begin
if IsAdminLoggedOn then begin if IsAdminInstallMode then begin
Result:=ExpandConstant('{pf}\{#MyAppName}'); Result:=ExpandConstant('{pf}\{#MyAppName}');
end else begin end else begin
Result:=ExpandConstant('{userpf}\{#MyAppName}'); Result:=ExpandConstant('{userpf}\{#MyAppName}');

Двоичные данные
windows-installer/signtool.exe Normal file

Двоичный файл не отображается.