Skip to content

[goreleaser]

[goreleaser] #15227

name: Go Releaser
on: [push]
jobs:
# build the goreleaser container cgo cross compiler container. Note: this wil not be applied until
# the next run since build-goreleaser and run-goreleaser are run concurrently. We expect github actions
# to fix this in a future version.
build-goreleaser:
runs-on: ubuntu-latest
outputs:
goreleaser-image: ${{ steps.name-export.outputs.TAG_NAME }}
permissions:
# always required
packages: write
# only required for private repos
actions: read
contents: write
steps:
- name: Git Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # needed if using new-from-rev (see: https://golangci-lint.run/usage/configuration/#issues-configuration)
- name: Cache Docker images.
uses: ScribeMD/docker-cache@0.3.6
with:
key: docker-release-${{ runner.os }}-${{ matrix.package }}
- uses: dorny/paths-filter@v3
name: check if any changes warrant a new build of goreleaser-cgo-cross-compiler
id: changes
with:
token: ${{ secrets.GITHUB_TOKEN }}
filters: |
src:
- 'docker/goreleaser/**'
-
name: Set up Docker Buildx
if: steps.changes.outputs.src == 'true'
uses: docker/setup-buildx-action@v2
with:
driver-opts: network=host
- name: Environment variables
# TODO: this if block needs to be run on every step now, but should be fixed in a future version: https://github.com/actions/runner/issues/662
if: steps.changes.outputs.src == 'true'
uses: franzdiebold/github-env-vars-action@v1.0.0
env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
-
name: Login to GitHub Container Registry
if: steps.changes.outputs.src == 'true'
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# we do this so we can use it in subseuqnet steps
- name: Export latest tag name
id: name-export
run:
echo "##[set-output name=TAG_NAME;]$(echo $LATEST_TAG_NAME)"
env:
LATEST_TAG_NAME: ghcr.io/synapsecns/sanguine-goreleaser:${{ hashFiles('docker/goreleaser/**') }}
-
name: Build and push
if: steps.changes.outputs.src == 'true'
uses: docker/build-push-action@v3
with:
context: .
push: true
file: ./docker/goreleaser/Dockerfile
# TODO this needs to be versioned
# Note: this automatically pushes the latest tag for sanguine-goreleaser even on branched workflows. While unlikely,
# this could break local devnets that rely on working versions of this image and as such the latest tag should only be pushed on master
# additionally, tags representing a specific version rather than the hash of the file should be considered for future use.
tags: ghcr.io/synapsecns/sanguine-goreleaser:latest,${{ steps.name-export.outputs.TAG_NAME }}
cache-from: type=registry,ref=ghcr.io/synapsecns/sanguine-goreleaser:buildcache
cache-to: type=registry,ref=ghcr.io/synapsecns/sanguine-goreleaser:buildcache,mode=max
# TODO: we should find a way for this not to be duplicated with go.yml
changes:
name: Change Detection
runs-on: ubuntu-latest
# see: https://stackoverflow.com/a/68414395
if: ${{ format('refs/heads/{0}', github.event.repository.default_branch) == github.ref || contains(github.event.head_commit.message, '[goreleaser]') }}
outputs:
# Expose matched filters as job 'packages' output variable
packages: ${{ steps.filter_go.outputs.changed_modules_deps }}
package_count: ${{ steps.length.outputs.FILTER_LENGTH }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: docker://ghcr.io/synapsecns/sanguine/git-changes-action:latest
id: filter_go
with:
github_token: ${{ secrets.WORKFLOW_PAT || secrets.GITHUB_TOKEN }}
- id: length
run: |
export FILTER_LENGTH=$(echo $FILTERED_PATHS | jq '. | length')
echo "##[set-output name=FILTER_LENGTH;]$(echo $FILTER_LENGTH)"
env:
FILTERED_PATHS: ${{ steps.filter_go.outputs.changed_modules_deps }}
run-goreleaser:
runs-on:
- namespace-profile-fast-goreleaser
needs: [build-goreleaser,changes]
if: ${{ needs.changes.outputs.package_count > 0 }}
permissions:
id-token: write
# always required
packages: write
# only required for private repos
actions: read
contents: write
strategy:
fail-fast: false
matrix:
# list of packages, if you update this update changes as well
package: ${{ fromJSON(needs.changes.outputs.packages) }}
container:
image: ${{ needs.build-goreleaser.outputs.goreleaser-image }}
env:
NSC_CACHE_PATH: ${{ env.NSC_CACHE_PATH }} # env.NSC_CACHE_PATH contains the path to Cache Volume directory, that is `/cache`.
volumes:
- /repo
- /cache:/cache
options: --cap-add=SYS_ADMIN # Required to by nscloud-cache-action to call `mount`.
steps:
- name: Git Checkout
uses: actions/checkout@v4
with:
fetch-depth: ${{ github.ref == 'refs/heads/master' && '0' || '1' }}
- name: Set up cache
if: ${{ !contains(runner.name, 'nsc') }}
uses: actions/cache@v4
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{matrix.package}}-${{ hashFiles(format('{0}/go.sum', matrix.package)) }}
restore-keys: |
${{ runner.os }}-go-${{matrix.package}}
- name: Setup Go cache
uses: namespacelabs/nscloud-cache-action@v1
if: ${{ contains(runner.name, 'nsc') }}
with:
cache: go
- name: Get branch name
id: branch-name
uses: tj-actions/branch-names@v6
- name: Bump version and push tag
id: tag_version
if: steps.branch-name.outputs.is_default == 'true'
uses: mathieudutour/github-tag-action@v6.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
tag_prefix: ${{matrix.package}}/v
release_branches: master
fetch_all_tags: true
- name: Tag Config
run: git config --global --add safe.directory /__w/sanguine/sanguine
-
name: Fetch all tags
if: steps.branch-name.outputs.is_default == 'true'
run: git fetch --force --tags
# get the tag we just created
- name: Git Fetch Unshallow
if: steps.branch-name.outputs.is_default == 'true'
run: git fetch
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@111c56156bcc6918c056dbef52164cfa583dc549 # v5.2.0
id: import_gpg
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
-
name: Login to GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Run GoReleaser (Release)
if: steps.branch-name.outputs.is_default == 'true'
run: goreleaser --timeout 900m --clean --debug -f ${{matrix.package}}/.goreleaser.yml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GONOSUM: '.*'
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
GOGC: 2000
GOMEMLIMIT: 6GiB
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
# use this to determine if we need goreleaser for a workflow
- name: Check For Docker Images
if: steps.branch-name.outputs.is_default != 'true'
id: image_check
run: |
# will be 0 if none present
has_images=$(yq eval '.dockers != null' ${{matrix.package}}/.goreleaser.yml)
echo "##[set-output name=has_images;]$(echo $has_images)"
- name: Run GoReleaser (Snapshot)
if: steps.branch-name.outputs.is_default != 'true' && steps.image_check.outputs.has_images == 'true'
run: goreleaser --timeout 900m --snapshot --clean --debug -f ${{matrix.package}}/.goreleaser.yml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GONOSUM: '.*'
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
GOGC: 20
GOMEMLIMIT: 6GiB
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
- name: Get Project Name
id: project_id
run: |
project_name=$(yq '.project_name' ${{matrix.package}}/.goreleaser.yml)
echo "##[set-output name=project_name;]$(echo $project_name)"
- name: Push Docker Images (Snapshot)
if: steps.branch-name.outputs.is_default != 'true' && steps.image_check.outputs.has_images == 'true'
run: |
# Load the number of docker configurations
docker_configs=$(yq e '.dockers | length' dist/config.yaml)
# Check if there are no docker configurations
if [ "$docker_configs" -eq "0" ]; then
echo "No docker images to push"
exit 0
fi
# Iterate through each docker configuration
i=0
while [ "$i" -lt "$docker_configs" ]; do
# Extract the first image template
image_template=$(yq e ".dockers[$i].image_templates[0]" dist/config.yaml)
# Extract the base name from the image template
image_name=$(echo "$image_template" | sed -E 's|^(.*):[^:]+$|\1|')
# Tag and push the docker image
docker tag "$image_name:latest" "$image_name:${GITHUB_SHA}"
docker push "$image_name:${GITHUB_SHA}"
i=$((i + 1))
done
env:
image_name: ${{ steps.project_id.outputs.project_name }}
- name: Zip Artifacts (Snapshot)
if: steps.branch-name.outputs.is_default != 'true' && steps.image_check.outputs.has_images == 'true'
run: |
ls
zip -rv ${{ steps.project_id.outputs.project_name }}.zip dist
- name: Push Artifacts (Snapshot)
if: steps.branch-name.outputs.is_default != 'true' && steps.image_check.outputs.has_images == 'true'
uses: actions/upload-artifact@v4
with:
name: ${{steps.project_id.outputs.project_name}}.zip
path: ${{steps.project_id.outputs.project_name}}.zip
- name: Refresh Report Card
if: steps.branch-name.outputs.is_default == 'true'
working-directory: ${{matrix.package}}/
run: |
module_name=$(go mod edit -json | jq -r '.Module.Path')
curl -X POST -F "repo=$module_name" https://goreportcard.com/checks