diff --git a/workflow-templates/assets/release-go-task/DistTasks.yml b/workflow-templates/assets/release-go-task/DistTasks.yml new file mode 100644 index 00000000..37784580 --- /dev/null +++ b/workflow-templates/assets/release-go-task/DistTasks.yml @@ -0,0 +1,212 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/release-go-task/DistTasks.yml +version: "3" + +# This taskfile is ideally meant to be project agnostic and could be dropped in +# on other Go projects with minimal or no changes. +# +# To use it simply add the following lines to your main taskfile: +# includes: +# dist: ./DistTasks.yml +# +# The following variables must be declared in the including taskfile for the +# build process to work correctly: +# * DIST_DIR: the folder that will contain the final binaries and packages +# * PROJECT_NAME: the name of the project, used in package name +# * VERSION: the version of the project, used in package name and checksum file +# * LD_FLAGS: flags used at build time +# +# The project MUST contain a LICENSE.txt file in the root folder or packaging will fail. + +tasks: + all: + desc: Build for distribution for all platforms + cmds: + - task: Windows_32bit + - task: Windows_64bit + - task: Linux_32bit + - task: Linux_64bit + - task: Linux_ARMv6 + - task: Linux_ARMv7 + - task: Linux_ARM64 + - task: macOS_64bit + + Windows_32bit: + desc: Builds Windows 32 bit binaries + dir: "{{ .DIST_DIR }}" + cmds: + - | + docker run -v `pwd`/..:/home/build -w /home/build \ + -e CGO_ENABLED=1 \ + {{ .CONTAINER }}:{{ .CONTAINER_TAG }} \ + --build-cmd "{{ .BUILD_COMMAND }}" \ + -p "{{ .BUILD_PLATFORM }}" + + zip {{ .PACKAGE_NAME}} {{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }}.exe ../LICENSE.txt -j + sha256sum {{ .PACKAGE_NAME }} >> {{ .CHECKSUM_FILE }} + + vars: + PLATFORM_DIR: "{{ .PROJECT_NAME }}_windows_386" + BUILD_COMMAND: "go build -o {{ .DIST_DIR }}/{{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }}.exe {{ .LDFLAGS }}" + BUILD_PLATFORM: "windows/386" + CONTAINER_TAG: "{{ .GO_VERSION }}-main" + PACKAGE_PLATFORM: "Windows_32bit" + PACKAGE_NAME: "{{ .PROJECT_NAME }}_{{ .VERSION }}_{{ .PACKAGE_PLATFORM }}.zip" + + Windows_64bit: + desc: Builds Windows 64 bit binaries + dir: "{{ .DIST_DIR }}" + cmds: + - | + docker run -v `pwd`/..:/home/build -w /home/build \ + -e CGO_ENABLED=1 \ + {{ .CONTAINER }}:{{ .CONTAINER_TAG }} \ + --build-cmd "{{ .BUILD_COMMAND }}" \ + -p "{{ .BUILD_PLATFORM }}" + + zip {{ .PACKAGE_NAME}} {{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }}.exe ../LICENSE.txt -j + sha256sum {{ .PACKAGE_NAME }} >> {{ .CHECKSUM_FILE }} + + vars: + PLATFORM_DIR: "{{ .PROJECT_NAME }}_windows_amd64" + BUILD_COMMAND: "go build -o {{ .DIST_DIR }}/{{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }}.exe {{ .LDFLAGS }}" + BUILD_PLATFORM: "windows/amd64" + CONTAINER_TAG: "{{ .GO_VERSION }}-main" + PACKAGE_PLATFORM: "Windows_64bit" + PACKAGE_NAME: "{{ .PROJECT_NAME }}_{{ .VERSION }}_{{ .PACKAGE_PLATFORM }}.zip" + + Linux_32bit: + desc: Builds Linux 32 bit binaries + dir: "{{ .DIST_DIR }}" + cmds: + - | + docker run -v `pwd`/..:/home/build -w /home/build \ + -e CGO_ENABLED=1 \ + {{ .CONTAINER }}:{{ .CONTAINER_TAG }} \ + --build-cmd "{{ .BUILD_COMMAND }}" \ + -p "{{ .BUILD_PLATFORM }}" + + tar cz -C {{ .PLATFORM_DIR }} {{ .PROJECT_NAME }} -C ../.. LICENSE.txt -f {{ .PACKAGE_NAME }} + sha256sum {{ .PACKAGE_NAME }} >> {{ .CHECKSUM_FILE }} + + vars: + PLATFORM_DIR: "{{ .PROJECT_NAME }}_linux_amd32" + BUILD_COMMAND: "go build -o {{ .DIST_DIR }}/{{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }} {{ .LDFLAGS }}" + BUILD_PLATFORM: "linux/386" + CONTAINER_TAG: "{{ .GO_VERSION }}-main" + PACKAGE_PLATFORM: "Linux_32bit" + PACKAGE_NAME: "{{ .PROJECT_NAME }}_{{ .VERSION }}_{{ .PACKAGE_PLATFORM }}.tar.gz" + + Linux_64bit: + desc: Builds Linux 64 bit binaries + dir: "{{ .DIST_DIR }}" + cmds: + - | + docker run -v `pwd`/..:/home/build -w /home/build \ + -e CGO_ENABLED=1 \ + {{ .CONTAINER }}:{{ .CONTAINER_TAG }} \ + --build-cmd "{{ .BUILD_COMMAND }}" \ + -p "{{ .BUILD_PLATFORM }}" + + tar cz -C {{ .PLATFORM_DIR }} {{ .PROJECT_NAME }} -C ../.. LICENSE.txt -f {{ .PACKAGE_NAME }} + sha256sum {{ .PACKAGE_NAME }} >> {{ .CHECKSUM_FILE }} + + vars: + PLATFORM_DIR: "{{ .PROJECT_NAME }}_linux_amd64" + BUILD_COMMAND: "go build -o {{ .DIST_DIR }}/{{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }} {{ .LDFLAGS }}" + BUILD_PLATFORM: "linux/amd64" + CONTAINER_TAG: "{{ .GO_VERSION }}-main" + PACKAGE_PLATFORM: "Linux_64bit" + PACKAGE_NAME: "{{ .PROJECT_NAME }}_{{ .VERSION }}_{{ .PACKAGE_PLATFORM }}.tar.gz" + + Linux_ARMv7: + desc: Builds Linux ARMv7 binaries + dir: "{{ .DIST_DIR }}" + cmds: + - | + docker run -v `pwd`/..:/home/build -w /home/build \ + -e CGO_ENABLED=1 \ + {{ .CONTAINER }}:{{ .CONTAINER_TAG }} \ + --build-cmd "{{ .BUILD_COMMAND }}" \ + -p "{{ .BUILD_PLATFORM }}" + + tar cz -C {{ .PLATFORM_DIR }} {{ .PROJECT_NAME }} -C ../.. LICENSE.txt -f {{ .PACKAGE_NAME }} + sha256sum {{ .PACKAGE_NAME }} >> {{ .CHECKSUM_FILE }} + + vars: + PLATFORM_DIR: "{{ .PROJECT_NAME }}_linux_arm_7" + BUILD_COMMAND: "go build -o {{ .DIST_DIR }}/{{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }} {{ .LDFLAGS }}" + BUILD_PLATFORM: "linux/armv7" + CONTAINER_TAG: "{{ .GO_VERSION }}-arm" + PACKAGE_PLATFORM: "Linux_ARMv7" + PACKAGE_NAME: "{{ .PROJECT_NAME }}_{{ .VERSION }}_{{ .PACKAGE_PLATFORM }}.tar.gz" + + Linux_ARMv6: + desc: Builds Linux ARMv6 binaries + dir: "{{ .DIST_DIR }}" + cmds: + - | + docker run -v `pwd`/..:/home/build -w /home/build \ + -e CGO_ENABLED=1 \ + {{ .CONTAINER }}:{{ .CONTAINER_TAG }} \ + --build-cmd "{{ .BUILD_COMMAND }}" \ + -p "{{ .BUILD_PLATFORM }}" + + tar cz -C {{ .PLATFORM_DIR }} {{ .PROJECT_NAME }} -C ../.. LICENSE.txt -f {{ .PACKAGE_NAME }} + sha256sum {{ .PACKAGE_NAME }} >> {{ .CHECKSUM_FILE }} + + vars: + PLATFORM_DIR: "{{ .PROJECT_NAME }}_linux_arm_6" + BUILD_COMMAND: "go build -o {{ .DIST_DIR }}/{{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }} {{ .LDFLAGS }}" + BUILD_PLATFORM: "linux/armv6" + CONTAINER_TAG: "{{ .GO_VERSION }}-arm" + PACKAGE_PLATFORM: "Linux_ARMv6" + PACKAGE_NAME: "{{ .PROJECT_NAME }}_{{ .VERSION }}_{{ .PACKAGE_PLATFORM }}.tar.gz" + + Linux_ARM64: + desc: Builds Linux ARM64 binaries + dir: "{{ .DIST_DIR }}" + cmds: + - | + docker run -v `pwd`/..:/home/build -w /home/build \ + -e CGO_ENABLED=1 \ + {{ .CONTAINER }}:{{ .CONTAINER_TAG }} \ + --build-cmd "{{ .BUILD_COMMAND }}" \ + -p "{{ .BUILD_PLATFORM }}" + + tar cz -C {{ .PLATFORM_DIR }} {{ .PROJECT_NAME }} -C ../.. LICENSE.txt -f {{ .PACKAGE_NAME }} + sha256sum {{ .PACKAGE_NAME }} >> {{ .CHECKSUM_FILE }} + + vars: + PLATFORM_DIR: "{{ .PROJECT_NAME }}_linux_arm_6" + BUILD_COMMAND: "go build -o {{ .DIST_DIR }}/{{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }} {{ .LDFLAGS }}" + BUILD_PLATFORM: "linux/arm64" + CONTAINER_TAG: "{{ .GO_VERSION }}-arm" + PACKAGE_PLATFORM: "Linux_ARM64" + PACKAGE_NAME: "{{ .PROJECT_NAME }}_{{ .VERSION }}_{{ .PACKAGE_PLATFORM }}.tar.gz" + + macOS_64bit: + desc: Builds Mac OS X 64 bit binaries + dir: "{{ .DIST_DIR }}" + cmds: + - | + docker run -v `pwd`/..:/home/build -w /home/build \ + -e CGO_ENABLED=1 \ + {{ .CONTAINER }}:{{ .CONTAINER_TAG }} \ + --build-cmd "{{ .BUILD_COMMAND }}" \ + -p "{{ .BUILD_PLATFORM }}" + + tar cz -C {{ .PLATFORM_DIR }} {{ .PROJECT_NAME }} -C ../.. LICENSE.txt -f {{ .PACKAGE_NAME }} + sha256sum {{ .PACKAGE_NAME }} >> {{ .CHECKSUM_FILE }} + + vars: + PLATFORM_DIR: "{{ .PROJECT_NAME }}_osx_darwin_amd64" + BUILD_COMMAND: "go build -o {{ .DIST_DIR }}/{{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }} {{ .LDFLAGS }}" + BUILD_PLATFORM: "darwin/amd64" + CONTAINER_TAG: "{{ .GO_VERSION }}-darwin" + PACKAGE_PLATFORM: "macOS_64bit" + PACKAGE_NAME: "{{ .PROJECT_NAME }}_{{ .VERSION }}_{{ .PACKAGE_PLATFORM }}.tar.gz" + +vars: + CONTAINER: "docker.elastic.co/beats-dev/golang-crossbuild" + GO_VERSION: "1.14.7" + CHECKSUM_FILE: "{{ .VERSION }}-checksums.txt" diff --git a/workflow-templates/assets/release-go-task/Taskfile.yml b/workflow-templates/assets/release-go-task/Taskfile.yml new file mode 100644 index 00000000..ed5f6f00 --- /dev/null +++ b/workflow-templates/assets/release-go-task/Taskfile.yml @@ -0,0 +1,29 @@ +# See: https://taskfile.dev/#/usage +version: "3" + +includes: + dist: ./DistTasks.yml + +vars: + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/release-go-task/Taskfile.yml + PROJECT_NAME: "arduino-cli" + DIST_DIR: "dist" + # build vars + COMMIT: + sh: echo "$(git log -n 1 --format=%h)" + TIMESTAMP: + sh: echo "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" + TIMESTAMP_SHORT: + sh: echo "{{now | date "20060102"}}" + TAG: + sh: echo "`git tag --points-at=HEAD 2> /dev/null | head -n1`" + VERSION: "{{ if .NIGHTLY }}nightly-{{ .TIMESTAMP_SHORT }}{{ else if .TAG }}{{ .TAG }}{{ else }}{{ .PACKAGE_NAME_PREFIX }}git-snapshot{{ end }}" + LDFLAGS: > + -ldflags + ' + -X github.com/arduino/arduino-cli/version.versionString={{.VERSION}} + -X github.com/arduino/arduino-cli/version.commit={{ .COMMIT }} + -X github.com/arduino/arduino-cli/version.date={{.TIMESTAMP}} + ' + +tasks: {} diff --git a/workflow-templates/assets/shared/gon.config.hcl b/workflow-templates/assets/shared/gon.config.hcl new file mode 100644 index 00000000..f749d86d --- /dev/null +++ b/workflow-templates/assets/shared/gon.config.hcl @@ -0,0 +1,14 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/release-go-task/gon.config.hcl +# See: https://github.com/mitchellh/gon#configuration-file +source = ["dist/arduino-cli_osx_darwin_amd64/arduino-cli"] +bundle_id = "cc.arduino.arduino-cli" + +sign { + application_identity = "Developer ID Application: ARDUINO SA (7KT7ZWMCJT)" +} + +# Ask Gon for zip output to force notarization process to take place. +# The CI will ignore the zip output, using the signed binary only. +zip { + output_path = "arduino-cli.zip" +} diff --git a/workflow-templates/dependabot/workflow-template-copies/.github/workflows/publish-go-nightly-task.yml b/workflow-templates/dependabot/workflow-template-copies/.github/workflows/publish-go-nightly-task.yml new file mode 100644 index 00000000..ff04204b --- /dev/null +++ b/workflow-templates/dependabot/workflow-template-copies/.github/workflows/publish-go-nightly-task.yml @@ -0,0 +1,133 @@ +# Source: https://github.com/arduino/.github/blob/master/workflow-templates/publish-go-nightly-task.md +name: Publish Nightly Build + +on: + schedule: + # run every day at 1AM + - cron: "0 1 * * *" + +jobs: + create-nightly-artifacts: + # This workflow is only of value to the arduino/arduino-cli repository and + # would always fail in forks + if: github.repository == 'arduino/arduino-cli' + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v1 + with: + fetch-depth: 0 + + - name: Install Taskfile + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Build + env: + NIGHTLY: true + run: task dist:all + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: dist + path: dist + + notarize-macos: + runs-on: macos-latest + needs: create-nightly-artifacts + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: dist + # to ensure compatibility with v1 + path: dist + + - name: Import Code-Signing Certificates + env: + KEYCHAIN: "sign.keychain" + INSTALLER_CERT_MAC_PATH: "/tmp/ArduinoCerts2020.p12" + run: | + echo "${{ secrets.INSTALLER_CERT_MAC_P12 }}" | base64 --decode > "${{ env.INSTALLER_CERT_MAC_PATH }}" + security create-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" "${{ env.KEYCHAIN }}" + security default-keychain -s "${{ env.KEYCHAIN }}" + security unlock-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" "${{ env.KEYCHAIN }}" + security import "${{ env.INSTALLER_CERT_MAC_PATH }}" -k "${{ env.KEYCHAIN }}" -f pkcs12 -A -T /usr/bin/codesign -P "${{ secrets.INSTALLER_CERT_MAC_PASSWORD }}" + security set-key-partition-list -S apple-tool:,apple: -s -k "${{ secrets.KEYCHAIN_PASSWORD }}" "${{ env.KEYCHAIN }}" + + - name: Install gon for code signing and app notarization + run: | + wget -q https://github.com/mitchellh/gon/releases/download/v0.2.3/gon_macos.zip + unzip gon_macos.zip -d /usr/local/bin + + - name: Sign and notarize binary + env: + AC_USERNAME: ${{ secrets.AC_USERNAME }} + AC_PASSWORD: ${{ secrets.AC_PASSWORD }} + run: | + gon gon.config.hcl + + - name: Re-package binary and update checksum + # This step performs the following: + # 1. Repackage the signed binary replaced in place by Gon (ignoring the output zip file) + # 2. Recalculate package checksum and replace it in the nnnnnn-checksums.txt file + run: | + # GitHub's upload/download-artifact@v2 actions don't preserve file permissions, + # so we need to add execution permission back until the action is made to do this. + chmod +x dist/arduino-cli_osx_darwin_amd64/arduino-cli + PACKAGE_FILENAME="$(basename dist/arduino-cli_nightly-*_macOS_64bit.tar.gz)" + tar -czvf "dist/$PACKAGE_FILENAME" \ + -C dist/arduino-cli_osx_darwin_amd64/ arduino-cli \ + -C ../../ LICENSE.txt + CLI_CHECKSUM="$(shasum -a 256 "dist/$PACKAGE_FILENAME" | cut -d " " -f 1)" + perl -pi -w -e "s/.*${PACKAGE_FILENAME}/${CLI_CHECKSUM} ${PACKAGE_FILENAME}/g;" dist/*-checksums.txt + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: dist + path: dist + + publish-nightly: + runs-on: ubuntu-latest + needs: notarize-macos + + steps: + - name: Download artifact + uses: actions/download-artifact@v2 + with: + name: dist + # to ensure compatibility with v1 + path: dist + + - name: Upload release files on Arduino downloads servers + uses: docker://plugins/s3 + env: + PLUGIN_SOURCE: "dist/*" + PLUGIN_TARGET: "/arduino-cli/nightly" + PLUGIN_STRIP_PREFIX: "dist/" + PLUGIN_BUCKET: ${{ secrets.DOWNLOADS_BUCKET }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + + - name: Report failure + if: failure() + uses: masci/datadog@v1 + with: + api-key: ${{ secrets.DD_API_KEY }} + events: | + - title: "Arduino CLI nightly build failed" + text: "Nightly build workflow has failed" + alert_type: "error" + host: ${{ github.repository }} + tags: + - "project:arduino-cli" + - "workflow:${{ github.workflow }}" diff --git a/workflow-templates/dependabot/workflow-template-copies/.github/workflows/release-go-task.yml b/workflow-templates/dependabot/workflow-template-copies/.github/workflows/release-go-task.yml new file mode 100644 index 00000000..6964c6ac --- /dev/null +++ b/workflow-templates/dependabot/workflow-template-copies/.github/workflows/release-go-task.yml @@ -0,0 +1,171 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/release-go-task.md +name: Release + +on: + push: + tags: + - "[0-9]+.[0-9]+.[0-9]+*" + +jobs: + create-release-artifacts: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v1 + with: + fetch-depth: 0 + + - name: Create changelog + uses: arduino/create-changelog@v1 + with: + tag-regex: '^[0-9]+\.[0-9]+\.[0-9]+.*$' + filter-regex: '^\[(skip|changelog)[ ,-](skip|changelog)\].*' + case-insensitive-regex: true + changelog-file-path: "dist/CHANGELOG.md" + + - name: Install Taskfile + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Build + run: task dist:all + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: dist + path: dist + + notarize-macos: + runs-on: macos-latest + needs: create-release-artifacts + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: dist + # to ensure compatibility with v1 + path: dist + + - name: Import Code-Signing Certificates + env: + KEYCHAIN: "sign.keychain" + INSTALLER_CERT_MAC_PATH: "/tmp/ArduinoCerts2020.p12" + run: | + echo "${{ secrets.INSTALLER_CERT_MAC_P12 }}" | base64 --decode > "${{ env.INSTALLER_CERT_MAC_PATH }}" + security create-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" "${{ env.KEYCHAIN }}" + security default-keychain -s "${{ env.KEYCHAIN }}" + security unlock-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" "${{ env.KEYCHAIN }}" + security import "${{ env.INSTALLER_CERT_MAC_PATH }}" -k "${{ env.KEYCHAIN }}" -f pkcs12 -A -T /usr/bin/codesign -P "${{ secrets.INSTALLER_CERT_MAC_PASSWORD }}" + security set-key-partition-list -S apple-tool:,apple: -s -k "${{ secrets.KEYCHAIN_PASSWORD }}" "${{ env.KEYCHAIN }}" + + - name: Install gon for code signing and app notarization + run: | + wget -q https://github.com/mitchellh/gon/releases/download/v0.2.3/gon_macos.zip + unzip gon_macos.zip -d /usr/local/bin + + - name: Sign and notarize binary + env: + AC_USERNAME: ${{ secrets.AC_USERNAME }} + AC_PASSWORD: ${{ secrets.AC_PASSWORD }} + run: | + gon gon.config.hcl + + - name: Re-package binary and update checksum + # This step performs the following: + # 1. Repackage the signed binary replaced in place by Gon (ignoring the output zip file) + # 2. Recalculate package checksum and replace it in the nnnnnn-checksums.txt file + run: | + # GitHub's upload/download-artifact@v2 actions don't preserve file permissions, + # so we need to add execution permission back until the action is made to do this. + chmod +x dist/arduino-cli_osx_darwin_amd64/arduino-cli + TAG="${GITHUB_REF/refs\/tags\//}" + tar -czvf "dist/arduino-cli_${TAG}_macOS_64bit.tar.gz" \ + -C dist/arduino-cli_osx_darwin_amd64/ arduino-cli \ + -C ../../ LICENSE.txt + CLI_CHECKSUM="$(shasum -a 256 "dist/arduino-cli_${TAG}_macOS_64bit.tar.gz" | cut -d " " -f 1)" + perl -pi -w -e "s/.*arduino-cli_${TAG}_macOS_64bit.tar.gz/${CLI_CHECKSUM} arduino-cli_${TAG}_macOS_64bit.tar.gz/g;" dist/*-checksums.txt + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: dist + path: dist + + create-release: + runs-on: ubuntu-latest + needs: notarize-macos + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Download artifact + uses: actions/download-artifact@v2 + with: + name: dist + # to ensure compatibility with v1 + path: dist + + - name: Read CHANGELOG + id: changelog + run: | + body="$(cat dist/CHANGELOG.md)" + body="${body//'%'/'%25'}" + body="${body//$'\n'/'%0A'}" + body="${body//$'\r'/'%0D'}" + echo "$body" + echo "::set-output name=BODY::$body" + + - name: Identify Prerelease + # This is a workaround while waiting for create-release action + # to implement auto pre-release based on tag + id: prerelease + run: | + wget -q -P /tmp https://github.com/fsaintjacques/semver-tool/archive/3.0.0.zip + unzip -p /tmp/3.0.0.zip semver-tool-3.0.0/src/semver >/tmp/semver && chmod +x /tmp/semver + if [[ "$(/tmp/semver get prerel "${GITHUB_REF/refs\/tags\//}")" ]]; then echo "::set-output name=IS_PRE::true"; fi + + - name: Create Github Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: ${{ github.ref }} + body: ${{ steps.changelog.outputs.BODY }} + draft: false + prerelease: ${{ steps.prerelease.outputs.IS_PRE }} + + - name: Upload release files on Github + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: dist/* + tag: ${{ github.ref }} + file_glob: true + + - name: Upload release files on Arduino downloads servers + uses: docker://plugins/s3 + env: + PLUGIN_SOURCE: "dist/*" + PLUGIN_TARGET: "/arduino-cli/" + PLUGIN_STRIP_PREFIX: "dist/" + PLUGIN_BUCKET: ${{ secrets.DOWNLOADS_BUCKET }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + + - name: Update Homebrew formula + if: steps.prerelease.outputs.IS_PRE != 'true' + uses: dawidd6/action-homebrew-bump-formula@v3 + with: + token: ${{ secrets.ARDUINOBOT_GITHUB_TOKEN }} + formula: arduino-cli diff --git a/workflow-templates/publish-go-nightly-task.md b/workflow-templates/publish-go-nightly-task.md new file mode 100644 index 00000000..e6bd6c83 --- /dev/null +++ b/workflow-templates/publish-go-nightly-task.md @@ -0,0 +1,69 @@ +# "Publish Nightly Build" workflow (Go, Task) + +Workflow file: [publish-go-nightly-task.yml](publish-go-nightly-task.yml) + +Publish nightly builds of a [Go](https://golang.org/) project. + +This is the version of the workflow for projects using the [Task](https://taskfile.dev/#/) task runner tool. + +## Assets + +See [the "Release" workflow (Go, Task) documentation](release-go-task.md#assets) + +## Configuration + +See [the "Release" workflow (Go, Task) documentation](release-go-task.md#configuration) + +In addition, the following [repository secret](https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository) must be defined: + +- `DD_API_KEY` - [Datadog](https://www.datadoghq.com/) API key. + +## Readme badge + +Markdown badge: + +```markdown +[![Publish Nightly Build status](https://github.com/REPO_OWNER/REPO_NAME/actions/workflows/publish-go-nightly-task.yml/badge.svg)](https://github.com/REPO_OWNER/REPO_NAME/actions/workflows/publish-go-nightly-task.yml) +``` + +Replace the `REPO_OWNER` and `REPO_NAME` placeholders in the URLs with the final repository owner and name ([example](https://raw.githubusercontent.com/arduino-libraries/ArduinoIoTCloud/master/README.md)). + +--- + +Asciidoc badge: + +```adoc +image:https://github.com/{repository-owner}/{repository-name}/actions/workflows/publish-go-nightly-task.yml/badge.svg["Publish Nightly Build status", link="https://github.com/{repository-owner}/{repository-name}/actions/workflows/publish-go-nightly-task.yml"] +``` + +Define the `{repository-owner}` and `{repository-name}` attributes and use them throughout the readme ([example](https://raw.githubusercontent.com/arduino-libraries/WiFiNINA/master/README.adoc)). + +## Commit message + +``` +Add CI workflow to publish nightly builds + +On a daily schedule: + +- Build the project for all supported platforms. +- Sign and notarize the macOS build. +- Upload the builds to Arduino's downloads server. + +This will enable everyone to participate to the project's development via beta testing. +``` + +## PR message + +```markdown +On a daily schedule: + +- Build the project for all supported platforms. +- Use [gon](https://github.com/mitchellh/gon) to sign and notarize the macOS build. +- Upload the builds to Arduino's downloads server. + +This will enable everyone to participate to the project's development via beta testing. +``` + +## Related + +- ["Release" workflow (Go, Task)](release-go-task.md) diff --git a/workflow-templates/publish-go-nightly-task.yml b/workflow-templates/publish-go-nightly-task.yml new file mode 100644 index 00000000..ff04204b --- /dev/null +++ b/workflow-templates/publish-go-nightly-task.yml @@ -0,0 +1,133 @@ +# Source: https://github.com/arduino/.github/blob/master/workflow-templates/publish-go-nightly-task.md +name: Publish Nightly Build + +on: + schedule: + # run every day at 1AM + - cron: "0 1 * * *" + +jobs: + create-nightly-artifacts: + # This workflow is only of value to the arduino/arduino-cli repository and + # would always fail in forks + if: github.repository == 'arduino/arduino-cli' + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v1 + with: + fetch-depth: 0 + + - name: Install Taskfile + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Build + env: + NIGHTLY: true + run: task dist:all + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: dist + path: dist + + notarize-macos: + runs-on: macos-latest + needs: create-nightly-artifacts + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: dist + # to ensure compatibility with v1 + path: dist + + - name: Import Code-Signing Certificates + env: + KEYCHAIN: "sign.keychain" + INSTALLER_CERT_MAC_PATH: "/tmp/ArduinoCerts2020.p12" + run: | + echo "${{ secrets.INSTALLER_CERT_MAC_P12 }}" | base64 --decode > "${{ env.INSTALLER_CERT_MAC_PATH }}" + security create-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" "${{ env.KEYCHAIN }}" + security default-keychain -s "${{ env.KEYCHAIN }}" + security unlock-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" "${{ env.KEYCHAIN }}" + security import "${{ env.INSTALLER_CERT_MAC_PATH }}" -k "${{ env.KEYCHAIN }}" -f pkcs12 -A -T /usr/bin/codesign -P "${{ secrets.INSTALLER_CERT_MAC_PASSWORD }}" + security set-key-partition-list -S apple-tool:,apple: -s -k "${{ secrets.KEYCHAIN_PASSWORD }}" "${{ env.KEYCHAIN }}" + + - name: Install gon for code signing and app notarization + run: | + wget -q https://github.com/mitchellh/gon/releases/download/v0.2.3/gon_macos.zip + unzip gon_macos.zip -d /usr/local/bin + + - name: Sign and notarize binary + env: + AC_USERNAME: ${{ secrets.AC_USERNAME }} + AC_PASSWORD: ${{ secrets.AC_PASSWORD }} + run: | + gon gon.config.hcl + + - name: Re-package binary and update checksum + # This step performs the following: + # 1. Repackage the signed binary replaced in place by Gon (ignoring the output zip file) + # 2. Recalculate package checksum and replace it in the nnnnnn-checksums.txt file + run: | + # GitHub's upload/download-artifact@v2 actions don't preserve file permissions, + # so we need to add execution permission back until the action is made to do this. + chmod +x dist/arduino-cli_osx_darwin_amd64/arduino-cli + PACKAGE_FILENAME="$(basename dist/arduino-cli_nightly-*_macOS_64bit.tar.gz)" + tar -czvf "dist/$PACKAGE_FILENAME" \ + -C dist/arduino-cli_osx_darwin_amd64/ arduino-cli \ + -C ../../ LICENSE.txt + CLI_CHECKSUM="$(shasum -a 256 "dist/$PACKAGE_FILENAME" | cut -d " " -f 1)" + perl -pi -w -e "s/.*${PACKAGE_FILENAME}/${CLI_CHECKSUM} ${PACKAGE_FILENAME}/g;" dist/*-checksums.txt + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: dist + path: dist + + publish-nightly: + runs-on: ubuntu-latest + needs: notarize-macos + + steps: + - name: Download artifact + uses: actions/download-artifact@v2 + with: + name: dist + # to ensure compatibility with v1 + path: dist + + - name: Upload release files on Arduino downloads servers + uses: docker://plugins/s3 + env: + PLUGIN_SOURCE: "dist/*" + PLUGIN_TARGET: "/arduino-cli/nightly" + PLUGIN_STRIP_PREFIX: "dist/" + PLUGIN_BUCKET: ${{ secrets.DOWNLOADS_BUCKET }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + + - name: Report failure + if: failure() + uses: masci/datadog@v1 + with: + api-key: ${{ secrets.DD_API_KEY }} + events: | + - title: "Arduino CLI nightly build failed" + text: "Nightly build workflow has failed" + alert_type: "error" + host: ${{ github.repository }} + tags: + - "project:arduino-cli" + - "workflow:${{ github.workflow }}" diff --git a/workflow-templates/release-go-task.md b/workflow-templates/release-go-task.md new file mode 100644 index 00000000..601ba741 --- /dev/null +++ b/workflow-templates/release-go-task.md @@ -0,0 +1,83 @@ +# "Release" workflow (Go, Task) + +Workflow file: [release-go-task.yml](release-go-task.yml) + +Make a production release of the [Go](https://golang.org/) project. + +This is the version of the workflow for projects using the [Task](https://taskfile.dev/#/) task runner tool. + +## Assets + +- [`Taskfile.yml`](assets/release-go-task/Taskfile.yml] - [variables](https://taskfile.dev/#/usage?id=variables) providing project-specific data to the build system. + - Install to: repository root (or merge into the existing `Taskfile.yml`) +- [`DistTasks.yml`](assets/release-go-task/DistTasks.yml] - general purpose tasks for making production builds of Go projects. + - Install to: repository root +- [`gon.config.hcl`](assets/shared/gon.config.hcl] - [gon](https://github.com/mitchellh/gon) configuration file for macOS signing and notarization. + - Install to: repository root + +## Configuration + +The following [repository secrets](https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository) must be defined: + +- `INSTALLER_CERT_MAC_P12` - the [Apple Developer ID](https://developer.apple.com/support/developer-id/) signing certificate, exported in [PKCS #12 format](https://en.wikipedia.org/wiki/PKCS_12) and then encoded into base64 as described [here](https://www.kencochrane.com/2020/08/01/build-and-sign-golang-binaries-for-macos-with-github-actions/#exporting-the-developer-certificate). +- `INSTALLER_CERT_MAC_PASSWORD` - the password used to encrypt the Apple Developer ID signing certificate during the export process. +- `AC_USERNAME` - the Apple ID username associated with the certificate. + - **Note**: not likely to be a problem when using Arduino's standard credentials, but in the event the username is a member of multiple Apple Developer Program teams, you will also need to define the App Store Connect provider via [the `AC_PROVIDER` environment variable](https://github.com/mitchellh/gon#configuration-file). You can use the ID of the certificate identity (e.g., `7KT7ZWMCJT`) for this. +- `AC_PASSWORD` - [App-specific password](https://support.apple.com/en-us/HT204397) created for the Apple ID. +- `DOWNLOADS_BUCKET` - [AWS bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html) on the downloads server. +- `AWS_ACCESS_KEY_ID` - [AWS access key ID](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) for the downloads server. +- `AWS_SECRET_ACCESS_KEY` - [AWS secret access key](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) for the downloads server. + +## Readme badge + +Markdown badge: + +```markdown +[![Release status](https://github.com/REPO_OWNER/REPO_NAME/actions/workflows/release-go-task.yml/badge.svg)](https://github.com/REPO_OWNER/REPO_NAME/actions/workflows/release-go-task.yml) +``` + +Replace the `REPO_OWNER` and `REPO_NAME` placeholders in the URLs with the final repository owner and name ([example](https://raw.githubusercontent.com/arduino-libraries/ArduinoIoTCloud/master/README.md)). + +--- + +Asciidoc badge: + +```adoc +image:https://github.com/{repository-owner}/{repository-name}/actions/workflows/release-go-task.yml/badge.svg["Release status", link="https://github.com/{repository-owner}/{repository-name}/actions/workflows/release-go-task.yml"] +``` + +Define the `{repository-owner}` and `{repository-name}` attributes and use them throughout the readme ([example](https://raw.githubusercontent.com/arduino-libraries/WiFiNINA/master/README.adoc)). + +## Commit message + +``` +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. +- Upload the builds to Arduino's downloads server. +``` + +## PR message + +```markdown +On every push of a tag named with a version format: + +- Build the project for all supported platforms. +- Use [gon](https://github.com/mitchellh/gon) to sign and notarize the macOS build. +- Create a [GitHub release](https://docs.github.com/en/github/administering-a-repository/releasing-projects-on-github/about-releases). + - Builds and checksums are attached as release assets + - A changelog generated by [`arduino/create-changelog](https://github.com/arduino/create-changelog) from the commit history is added to the release description + - If the tag has [a pre-release version suffix](https://semver.org/), the GitHub release will be marked as a pre-release. +- Upload the builds to Arduino's downloads server. +``` + +## Related + +- ["Publish Nightly Build" workflow (Go, Task)](publish-go-nightly-task.md) diff --git a/workflow-templates/release-go-task.yml b/workflow-templates/release-go-task.yml new file mode 100644 index 00000000..6964c6ac --- /dev/null +++ b/workflow-templates/release-go-task.yml @@ -0,0 +1,171 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/release-go-task.md +name: Release + +on: + push: + tags: + - "[0-9]+.[0-9]+.[0-9]+*" + +jobs: + create-release-artifacts: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v1 + with: + fetch-depth: 0 + + - name: Create changelog + uses: arduino/create-changelog@v1 + with: + tag-regex: '^[0-9]+\.[0-9]+\.[0-9]+.*$' + filter-regex: '^\[(skip|changelog)[ ,-](skip|changelog)\].*' + case-insensitive-regex: true + changelog-file-path: "dist/CHANGELOG.md" + + - name: Install Taskfile + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Build + run: task dist:all + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: dist + path: dist + + notarize-macos: + runs-on: macos-latest + needs: create-release-artifacts + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: dist + # to ensure compatibility with v1 + path: dist + + - name: Import Code-Signing Certificates + env: + KEYCHAIN: "sign.keychain" + INSTALLER_CERT_MAC_PATH: "/tmp/ArduinoCerts2020.p12" + run: | + echo "${{ secrets.INSTALLER_CERT_MAC_P12 }}" | base64 --decode > "${{ env.INSTALLER_CERT_MAC_PATH }}" + security create-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" "${{ env.KEYCHAIN }}" + security default-keychain -s "${{ env.KEYCHAIN }}" + security unlock-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" "${{ env.KEYCHAIN }}" + security import "${{ env.INSTALLER_CERT_MAC_PATH }}" -k "${{ env.KEYCHAIN }}" -f pkcs12 -A -T /usr/bin/codesign -P "${{ secrets.INSTALLER_CERT_MAC_PASSWORD }}" + security set-key-partition-list -S apple-tool:,apple: -s -k "${{ secrets.KEYCHAIN_PASSWORD }}" "${{ env.KEYCHAIN }}" + + - name: Install gon for code signing and app notarization + run: | + wget -q https://github.com/mitchellh/gon/releases/download/v0.2.3/gon_macos.zip + unzip gon_macos.zip -d /usr/local/bin + + - name: Sign and notarize binary + env: + AC_USERNAME: ${{ secrets.AC_USERNAME }} + AC_PASSWORD: ${{ secrets.AC_PASSWORD }} + run: | + gon gon.config.hcl + + - name: Re-package binary and update checksum + # This step performs the following: + # 1. Repackage the signed binary replaced in place by Gon (ignoring the output zip file) + # 2. Recalculate package checksum and replace it in the nnnnnn-checksums.txt file + run: | + # GitHub's upload/download-artifact@v2 actions don't preserve file permissions, + # so we need to add execution permission back until the action is made to do this. + chmod +x dist/arduino-cli_osx_darwin_amd64/arduino-cli + TAG="${GITHUB_REF/refs\/tags\//}" + tar -czvf "dist/arduino-cli_${TAG}_macOS_64bit.tar.gz" \ + -C dist/arduino-cli_osx_darwin_amd64/ arduino-cli \ + -C ../../ LICENSE.txt + CLI_CHECKSUM="$(shasum -a 256 "dist/arduino-cli_${TAG}_macOS_64bit.tar.gz" | cut -d " " -f 1)" + perl -pi -w -e "s/.*arduino-cli_${TAG}_macOS_64bit.tar.gz/${CLI_CHECKSUM} arduino-cli_${TAG}_macOS_64bit.tar.gz/g;" dist/*-checksums.txt + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: dist + path: dist + + create-release: + runs-on: ubuntu-latest + needs: notarize-macos + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Download artifact + uses: actions/download-artifact@v2 + with: + name: dist + # to ensure compatibility with v1 + path: dist + + - name: Read CHANGELOG + id: changelog + run: | + body="$(cat dist/CHANGELOG.md)" + body="${body//'%'/'%25'}" + body="${body//$'\n'/'%0A'}" + body="${body//$'\r'/'%0D'}" + echo "$body" + echo "::set-output name=BODY::$body" + + - name: Identify Prerelease + # This is a workaround while waiting for create-release action + # to implement auto pre-release based on tag + id: prerelease + run: | + wget -q -P /tmp https://github.com/fsaintjacques/semver-tool/archive/3.0.0.zip + unzip -p /tmp/3.0.0.zip semver-tool-3.0.0/src/semver >/tmp/semver && chmod +x /tmp/semver + if [[ "$(/tmp/semver get prerel "${GITHUB_REF/refs\/tags\//}")" ]]; then echo "::set-output name=IS_PRE::true"; fi + + - name: Create Github Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: ${{ github.ref }} + body: ${{ steps.changelog.outputs.BODY }} + draft: false + prerelease: ${{ steps.prerelease.outputs.IS_PRE }} + + - name: Upload release files on Github + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: dist/* + tag: ${{ github.ref }} + file_glob: true + + - name: Upload release files on Arduino downloads servers + uses: docker://plugins/s3 + env: + PLUGIN_SOURCE: "dist/*" + PLUGIN_TARGET: "/arduino-cli/" + PLUGIN_STRIP_PREFIX: "dist/" + PLUGIN_BUCKET: ${{ secrets.DOWNLOADS_BUCKET }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + + - name: Update Homebrew formula + if: steps.prerelease.outputs.IS_PRE != 'true' + uses: dawidd6/action-homebrew-bump-formula@v3 + with: + token: ${{ secrets.ARDUINOBOT_GITHUB_TOKEN }} + formula: arduino-cli