Skip to content

Commit cf74419

Browse files
committed
Add CI workflow to publish releases
On every push of a tag named with a version format: - Build the project for all supported platforms. - Sign and notarize the macOS build. - Create a GitHub release. - Builds and checksums are attached as release assets - A changelog generated from the commit history is added to the release description - If the tag has a pre-release version suffix, the GitHub release will be marked as a pre-release.
1 parent edf7683 commit cf74419

File tree

6 files changed

+408
-1
lines changed

6 files changed

+408
-1
lines changed
+174
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/release-go-task.md
2+
name: Release
3+
4+
env:
5+
# As defined by the Taskfile's PROJECT_NAME variable
6+
PROJECT_NAME: arduino-cslt
7+
# As defined by the Taskfile's DIST_DIR variable
8+
DIST_DIR: dist
9+
# The project's folder on Arduino's download server for uploading builds
10+
# AWS_PLUGIN_TARGET: TODO
11+
ARTIFACT_NAME: dist
12+
# See: https://github.com/actions/setup-go/tree/v2#readme
13+
GO_VERSION: 1.16
14+
15+
on:
16+
push:
17+
tags:
18+
- "[0-9]+.[0-9]+.[0-9]+*"
19+
20+
jobs:
21+
create-release-artifacts:
22+
runs-on: ubuntu-latest
23+
24+
steps:
25+
- name: Checkout repository
26+
uses: actions/checkout@v2
27+
with:
28+
fetch-depth: 0
29+
30+
- name: Create changelog
31+
uses: arduino/create-changelog@v1
32+
with:
33+
tag-regex: '^[0-9]+\.[0-9]+\.[0-9]+.*$'
34+
filter-regex: '^\[(skip|changelog)[ ,-](skip|changelog)\].*'
35+
case-insensitive-regex: true
36+
changelog-file-path: "${{ env.DIST_DIR }}/CHANGELOG.md"
37+
38+
# enable this if not using docker containers to build
39+
- name: Install Go
40+
uses: actions/setup-go@v2
41+
with:
42+
go-version: ${{ env.GO_VERSION }}
43+
44+
- name: Install Task
45+
uses: arduino/setup-task@v1
46+
with:
47+
repo-token: ${{ secrets.GITHUB_TOKEN }}
48+
version: 3.x
49+
50+
- name: Build
51+
run: task dist:all
52+
53+
- name: Upload artifacts
54+
uses: actions/upload-artifact@v2
55+
with:
56+
if-no-files-found: error
57+
name: ${{ env.ARTIFACT_NAME }}
58+
path: ${{ env.DIST_DIR }}
59+
60+
notarize-macos:
61+
runs-on: macos-latest
62+
needs: create-release-artifacts
63+
64+
steps:
65+
- name: Checkout repository
66+
uses: actions/checkout@v2
67+
68+
- name: Download artifacts
69+
uses: actions/download-artifact@v2
70+
with:
71+
name: ${{ env.ARTIFACT_NAME }}
72+
path: ${{ env.DIST_DIR }}
73+
74+
- name: Import Code-Signing Certificates
75+
env:
76+
KEYCHAIN: "sign.keychain"
77+
INSTALLER_CERT_MAC_PATH: "/tmp/ArduinoCerts2020.p12"
78+
KEYCHAIN_PASSWORD: keychainpassword # Arbitrary password for a keychain that exists only for the duration of the job, so not secret
79+
run: |
80+
echo "${{ secrets.INSTALLER_CERT_MAC_P12 }}" | base64 --decode > "${{ env.INSTALLER_CERT_MAC_PATH }}"
81+
security create-keychain -p "${{ env.KEYCHAIN_PASSWORD }}" "${{ env.KEYCHAIN }}"
82+
security default-keychain -s "${{ env.KEYCHAIN }}"
83+
security unlock-keychain -p "${{ env.KEYCHAIN_PASSWORD }}" "${{ env.KEYCHAIN }}"
84+
security import \
85+
"${{ env.INSTALLER_CERT_MAC_PATH }}" \
86+
-k "${{ env.KEYCHAIN }}" \
87+
-f pkcs12 \
88+
-A \
89+
-T "/usr/bin/codesign" \
90+
-P "${{ secrets.INSTALLER_CERT_MAC_PASSWORD }}"
91+
security set-key-partition-list \
92+
-S apple-tool:,apple: \
93+
-s \
94+
-k "${{ env.KEYCHAIN_PASSWORD }}" \
95+
"${{ env.KEYCHAIN }}"
96+
97+
- name: Install gon for code signing and app notarization
98+
run: |
99+
wget -q https://github.com/mitchellh/gon/releases/download/v0.2.3/gon_macos.zip
100+
unzip gon_macos.zip -d /usr/local/bin
101+
102+
- name: Sign and notarize binary
103+
env:
104+
AC_USERNAME: ${{ secrets.AC_USERNAME }}
105+
AC_PASSWORD: ${{ secrets.AC_PASSWORD }}
106+
run: |
107+
gon gon.config.hcl
108+
109+
- name: Re-package binary and update checksum
110+
# This step performs the following:
111+
# 1. Repackage the signed binary replaced in place by Gon (ignoring the output zip file)
112+
# 2. Recalculate package checksum and replace it in the nnnnnn-checksums.txt file
113+
run: |
114+
# GitHub's upload/download-artifact@v2 actions don't preserve file permissions,
115+
# so we need to add execution permission back until the action is made to do this.
116+
chmod +x ${{ env.DIST_DIR }}/${{ env.PROJECT_NAME }}_osx_darwin_amd64/${{ env.PROJECT_NAME }}
117+
TAG="${GITHUB_REF/refs\/tags\//}"
118+
tar -czvf "${{ env.DIST_DIR }}/${{ env.PROJECT_NAME }}_${TAG}_macOS_64bit.tar.gz" \
119+
-C ${{ env.DIST_DIR }}/${{ env.PROJECT_NAME }}_osx_darwin_amd64/ ${{ env.PROJECT_NAME }} \
120+
-C ../../ LICENSE.txt
121+
CHECKSUM="$(shasum -a 256 ${{ env.DIST_DIR }}/${{ env.PROJECT_NAME }}_${TAG}_macOS_64bit.tar.gz | cut -d " " -f 1)"
122+
perl \
123+
-pi \
124+
-w \
125+
-e "s/.*${{ env.PROJECT_NAME }}_${TAG}_macOS_64bit.tar.gz/${CHECKSUM} ${{ env.PROJECT_NAME }}_${TAG}_macOS_64bit.tar.gz/g;" \
126+
${{ env.DIST_DIR }}/*-checksums.txt
127+
128+
- name: Upload artifacts
129+
uses: actions/upload-artifact@v2
130+
with:
131+
if-no-files-found: error
132+
name: ${{ env.ARTIFACT_NAME }}
133+
path: ${{ env.DIST_DIR }}
134+
135+
create-release:
136+
runs-on: ubuntu-latest
137+
needs: notarize-macos
138+
139+
steps:
140+
- name: Download artifact
141+
uses: actions/download-artifact@v2
142+
with:
143+
name: ${{ env.ARTIFACT_NAME }}
144+
path: ${{ env.DIST_DIR }}
145+
146+
- name: Identify Prerelease
147+
# This is a workaround while waiting for create-release action
148+
# to implement auto pre-release based on tag
149+
id: prerelease
150+
run: |
151+
wget -q -P /tmp https://github.com/fsaintjacques/semver-tool/archive/3.0.0.zip
152+
unzip -p /tmp/3.0.0.zip semver-tool-3.0.0/src/semver >/tmp/semver && chmod +x /tmp/semver
153+
if [[ "$(/tmp/semver get prerel "${GITHUB_REF/refs\/tags\//}")" ]]; then echo "::set-output name=IS_PRE::true"; fi
154+
155+
- name: Create Github Release and upload artifacts
156+
uses: ncipollo/release-action@v1
157+
with:
158+
token: ${{ secrets.GITHUB_TOKEN }}
159+
bodyFile: ${{ env.DIST_DIR }}/CHANGELOG.md
160+
draft: false
161+
prerelease: ${{ steps.prerelease.outputs.IS_PRE }}
162+
# NOTE: "Artifact is a directory" warnings are expected and don't indicate a problem
163+
# (all the files we need are in the DIST_DIR root)
164+
artifacts: ${{ env.DIST_DIR }}/*
165+
166+
# - name: Upload release files on Arduino downloads servers
167+
# uses: docker://plugins/s3
168+
# env:
169+
# PLUGIN_SOURCE: "${{ env.DIST_DIR }}/*"
170+
# PLUGIN_TARGET: ${{ env.AWS_PLUGIN_TARGET }}
171+
# PLUGIN_STRIP_PREFIX: "${{ env.DIST_DIR }}/"
172+
# PLUGIN_BUCKET: ${{ secrets.DOWNLOADS_BUCKET }}
173+
# AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
174+
# AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
arduino-cslt
22
.vscode
3-
lib*
3+
lib*
4+
dist

DistTasks.yml

+166
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/release-go-task/go-crosscompile/DistTasks.yml
2+
version: "3"
3+
4+
# This taskfile is ideally meant to be project agnostic and could be dropped in
5+
# on other Go projects with minimal or no changes.
6+
#
7+
# To use it simply add the following lines to your main taskfile:
8+
# includes:
9+
# dist: ./DistTasks.yml
10+
#
11+
# The following variables must be declared in the including taskfile for the
12+
# build process to work correctly:
13+
# * DIST_DIR: the folder that will contain the final binaries and packages
14+
# * PROJECT_NAME: the name of the project, used in package name
15+
# * VERSION: the version of the project, used in package name and checksum file
16+
# * LD_FLAGS: flags used at build time
17+
#
18+
# The project MUST contain a LICENSE.txt file in the root folder or packaging will fail.
19+
20+
vars:
21+
CHECKSUM_FILE: "{{.VERSION}}-checksums.txt"
22+
23+
tasks:
24+
all:
25+
desc: Build for distribution for all platforms
26+
cmds:
27+
- task: Windows_32bit
28+
- task: Windows_64bit
29+
- task: Linux_32bit
30+
- task: Linux_64bit
31+
- task: Linux_ARMv6
32+
- task: Linux_ARMv7
33+
- task: Linux_ARM64
34+
- task: macOS_64bit
35+
36+
Windows_32bit:
37+
desc: Builds Windows 32 bit binaries
38+
env:
39+
GOOS: "windows"
40+
GOARCH: "386"
41+
GO386: "softfloat"
42+
cmds:
43+
- |
44+
go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}}.exe {{.LDFLAGS}}
45+
cd {{.DIST_DIR}}
46+
zip {{.PACKAGE_NAME}} {{.PLATFORM_DIR}}/{{.PROJECT_NAME}}.exe ../LICENSE.txt -j
47+
sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}
48+
vars:
49+
PLATFORM_DIR: "{{.PROJECT_NAME}}_windows_386"
50+
PACKAGE_PLATFORM: "Windows_32bit"
51+
PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.zip"
52+
53+
Windows_64bit:
54+
desc: Builds Windows 64 bit binaries
55+
env:
56+
GOOS: "windows"
57+
GOARCH: "amd64"
58+
cmds:
59+
- |
60+
go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}}.exe {{.LDFLAGS}}
61+
cd {{.DIST_DIR}}
62+
zip {{.PACKAGE_NAME}} {{.PLATFORM_DIR}}/{{.PROJECT_NAME}}.exe ../LICENSE.txt -j
63+
sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}
64+
vars:
65+
PLATFORM_DIR: "{{.PROJECT_NAME}}_windows_amd64"
66+
PACKAGE_PLATFORM: "Windows_64bit"
67+
PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.zip"
68+
69+
Linux_32bit:
70+
desc: Builds Linux 32 bit binaries
71+
env:
72+
GOOS: "linux"
73+
GOARCH: "386"
74+
GO386: "softfloat"
75+
cmds:
76+
- |
77+
go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}}
78+
cd {{.DIST_DIR}}
79+
tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt -f {{.PACKAGE_NAME}}
80+
sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}
81+
vars:
82+
PLATFORM_DIR: "{{.PROJECT_NAME}}_linux_amd32"
83+
PACKAGE_PLATFORM: "Linux_32bit"
84+
PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz"
85+
86+
Linux_64bit:
87+
desc: Builds Linux 64 bit binaries
88+
env:
89+
GOOS: "linux"
90+
GOARCH: "amd64"
91+
cmds:
92+
- |
93+
go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}}
94+
cd {{.DIST_DIR}}
95+
tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt -f {{.PACKAGE_NAME}}
96+
sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}
97+
vars:
98+
PLATFORM_DIR: "{{.PROJECT_NAME}}_linux_amd64"
99+
PACKAGE_PLATFORM: "Linux_64bit"
100+
PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz"
101+
102+
Linux_ARMv7:
103+
desc: Builds Linux ARMv7 binaries
104+
env:
105+
GOOS: "linux"
106+
GOARCH: "arm"
107+
GOARM: 7
108+
cmds:
109+
- |
110+
go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}}
111+
cd {{.DIST_DIR}}
112+
tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt -f {{.PACKAGE_NAME}}
113+
sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}
114+
vars:
115+
PLATFORM_DIR: "{{.PROJECT_NAME}}_linux_arm_7"
116+
PACKAGE_PLATFORM: "Linux_ARMv7"
117+
PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz"
118+
119+
Linux_ARMv6:
120+
desc: Builds Linux ARMv6 binaries
121+
env:
122+
GOOS: "linux"
123+
GOARCH: "arm"
124+
GOARM: 6
125+
cmds:
126+
- |
127+
go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}}
128+
cd {{.DIST_DIR}}
129+
tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt -f {{.PACKAGE_NAME}}
130+
sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}
131+
vars:
132+
PLATFORM_DIR: "{{.PROJECT_NAME}}_linux_arm_6"
133+
PACKAGE_PLATFORM: "Linux_ARMv6"
134+
PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz"
135+
136+
Linux_ARM64:
137+
desc: Builds Linux ARM64 binaries
138+
env:
139+
GOOS: "linux"
140+
GOARCH: "arm64"
141+
cmds:
142+
- |
143+
go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}}
144+
cd {{.DIST_DIR}}
145+
tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt -f {{.PACKAGE_NAME}}
146+
sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}
147+
vars:
148+
PLATFORM_DIR: "{{.PROJECT_NAME}}_linux_arm_64"
149+
PACKAGE_PLATFORM: "Linux_ARM64"
150+
PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz"
151+
152+
macOS_64bit:
153+
desc: Builds Mac OS X 64 bit binaries
154+
env:
155+
GOOS: "darwin"
156+
GOARCH: "amd64"
157+
cmds:
158+
- |
159+
go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}}
160+
cd {{.DIST_DIR}}
161+
tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt -f {{.PACKAGE_NAME}}
162+
sha256sum {{.PACKAGE_NAME}} >> {{.CHECKSUM_FILE}}
163+
vars:
164+
PLATFORM_DIR: "{{.PROJECT_NAME}}_osx_darwin_amd64"
165+
PACKAGE_PLATFORM: "macOS_64bit"
166+
PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz"

Taskfile.yml

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# See: https://taskfile.dev/#/usage
2+
version: "3"
3+
4+
includes:
5+
dist: ./DistTasks.yml
6+
7+
vars:
8+
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/release-go-task/Taskfile.yml
9+
PROJECT_NAME: arduino-cslt
10+
DIST_DIR: "dist"
11+
# build vars
12+
COMMIT:
13+
sh: echo "$(git log --no-show-signature -n 1 --format=%h)"
14+
TIMESTAMP:
15+
sh: echo "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
16+
TIMESTAMP_SHORT:
17+
sh: echo "{{now | date "20060102"}}"
18+
TAG:
19+
sh: echo "$(git tag --points-at=HEAD 2> /dev/null | head -n1)"
20+
VERSION: "{{if .NIGHTLY}}nightly-{{.TIMESTAMP_SHORT}}{{else if .TAG}}{{.TAG}}{{else}}{{.PACKAGE_NAME_PREFIX}}git-snapshot{{end}}"
21+
CONFIGURATION_PACKAGE: github.com/arduino/arduino-cslt/version
22+
# Path of the project's primary Go module:
23+
DEFAULT_GO_MODULE_PATH: ./
24+
DEFAULT_GO_PACKAGES:
25+
sh: |
26+
echo $(cd {{default .DEFAULT_GO_MODULE_PATH .GO_MODULE_PATH}} && go list ./... | tr '\n' ' ' || echo '"ERROR: Unable to discover Go packages"')
27+
# `-ldflags` flag to use for `go build` command
28+
LDFLAGS: >-
29+
-ldflags
30+
'
31+
-X {{.CONFIGURATION_PACKAGE}}.Version={{.VERSION}}
32+
-X {{.CONFIGURATION_PACKAGE}}.Commit={{.COMMIT}}
33+
-X {{.CONFIGURATION_PACKAGE}}.Timestamp={{.TIMESTAMP}}
34+
'
35+
tasks:
36+
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/go-task/Taskfile.yml
37+
go:build:
38+
desc: Build the Go code
39+
dir: "{{.DEFAULT_GO_MODULE_PATH}}"
40+
cmds:
41+
- go build -v {{.LDFLAGS}}

0 commit comments

Comments
 (0)