6 minutes
Gitea, Golang, GoReleaser and Drone CI - Part 3
- Gitea, Golang, GoReleaser and Drone CI - Part 1
- Gitea, Golang, GoReleaser and Drone CI - Part 2
- Gitea, Golang, GoReleaser and Drone CI - Part 3 <- You are Here
- Gitea, Golang, GoReleaser and Drone CI - Part 4
Howdy again, hope you’re all going well. Let’s get right to it.
GoReleaser is already installed in the devcontainer environment for you, let’s check that it’s happy.
$ pwd
/workspaces/go-goreleaser-drone-example/crimp-city
$ goreleaser -h
GoReleaser is a release automation tool for Go projects.
Its goal is to simplify the build, release and publish steps while providing
variant customization options for all steps.
GoReleaser is built for CI tools, you only need to download and execute it
in your build script. Of course, you can also install it locally if you wish.
You can also customize your entire release process through a
single .goreleaser.yml file.
Usage:
goreleaser [command]
Available Commands:
build Builds the current project
check Checks if configuration is valid
completion generate the autocompletion script for the specified shell
help Help about any command
init Generates a .goreleaser.yml file
jsonschema outputs goreleaser's JSON schema
release Releases the current project
Flags:
--debug Enable debug mode
-h, --help help for goreleaser
-v, --version version for goreleaser
Use "goreleaser [command] --help" for more information about a command.
Excellent, everything seems to be in order here. Let’s generate the default config.
$ goreleaser init
• Generating .goreleaser.yml file
• config created; please edit accordingly to your needs file=.goreleaser.yml
It should look something like the below, though I’ve made some small changes to make it only build for 64-bit linux hosts.
before:
hooks:
- go mod tidy
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
goarch:
- amd64
archives:
- replacements:
linux: Linux
amd64: x86_64
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ incpatch .Version }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
As usual, let’s test this works before moving on.
$ goreleaser release --snapshot --rm-dist
• releasing...
• loading config file file=.goreleaser.yml
• loading environment variables
• getting and validating git state
• ignoring errors because this is a snapshot error=git doesn't contain any tags. Either add a tag or use --snapshot
• building... commit=9dac672bfae18f00162a9c96a6bc87197c652d4b latest tag=v0.0.0
• pipe skipped error=disabled during snapshot mode
• parsing tag
• running before hooks
• running hook=go mod tidy
• setting defaults
• snapshotting
• github/gitlab/gitea releases
• project name
• loading go mod information
• building binaries
• universal binaries
• creating source archive
• archives
• linux packages
• snapcraft packages
• calculating checksums
• signing artifacts
• signing docker images
• docker images
• docker manifests
• artifactory
• blobs
• homebrew tap formula
• gofish fish food cookbook
• scoop manifests
• discord
• reddit
• slack
• teams
• twitter
• smtp
• mattermost
• milestones
• telegram
• snapshotting
• building snapshot... version=0.0.1-next
• checking ./dist
• --rm-dist is set, cleaning it up
• loading go mod information
• writing effective config file
• writing config=dist/config.yaml
• building binaries
• building binary=/workspaces/go-goreleaser-drone-example/crimp-city/dist/crimp-city_linux_amd64/crimp-city
• archives
• creating archive=dist/crimp-city_0.0.1-next_Linux_x86_64.tar.gz
• calculating checksums
• checksumming file=crimp-city_0.0.1-next_Linux_x86_64.tar.gz
• release succeeded after 0.29s
Okay, good, and what about the binary that it actually produced?
$ ./dist/crimp-city_linux_amd64/crimp-city
█░█ █▀▀ █░░ █░░ █▀█ █░█░█ █▀█ █▀█ █░░ █▀▄
█▀█ ██▄ █▄▄ █▄▄ █▄█ ▀▄▀▄▀ █▄█ █▀▄ █▄▄ █▄▀ version 0.0.1-next
Nice! But what’s this? The version has changed from dev
to 0.0.1-next
. Why? Well, Go lets you pass in variables at build time, and GoReleaser has some defaults that it will pass in.
# Custom ldflags templates.
# Default is `-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser`.
Normally GoReleaser will do some magic with the most recent git tag for the version, but we don’t currently have a tag, so it supplies 0.0.1-next
for us.
So, we have a Go program and a local working GoReleaser config. Let’s make things official and actually make a release in Gitea. We’ll need to create an API token for GoReleaser to use, and tell GoReleaser how to reach Gitea.
GoReleaser requires an API token to deploy the artifacts to Gitea. You can create one in Settings | Applications | Generate New Token page of your Gitea instance.
This token should be added to the environment variables as GITEA_TOKEN.
Set the token you just created.
export GITEA_TOKEN=<your-token-here>
Update the .goreleaser.yml
configuration.
Now, I think there’s a bug in the current version of GoReleaser. I’ve raised an issue for it, but basically, the release block included below shouldn’t be necessary. If you’re following along, try without it and if you get a 404 error, add it in.I found a bug in GoReleaser, and it was fixed almost immediately! Awesome work. If you’re on v1.1.0 of GoReleaser, you can leave the commented part of the block below as is. If you’re on a lower version, you need to uncomment it. Or just upgrade. 🤷
gitea_urls:
api: http://gitea:3000/api/v1/
download: http://gitea:3000
# release:
# gitea:
# owner: gitea
# name: crimp-city
Now commit the changes, tag the commit and push it to Gitea.
$ git add .goreleaser.yml
$ git commit -m "Update gitea goreleaser config"
[master 4836926] Update gitea goreleaser config
1 file changed, 4 insertions(+)
$ git tag -a v0.1 -m "First release"
$ git push origin v0.1
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
remote: . Processing 1 references
remote: Processed 1 references in total
To http://gitea:3000/gitea/crimp-city.git
* [new tag] v0.1 -> v0.1
$ goreleaser release --rm-dist
• releasing...
• loading config file file=.goreleaser.yml
• loading environment variables
• getting and validating git state
• building... commit=4836926dc37b8e8cac913f7f0e6f8ae5d2376c06 latest tag=v0.1
• parsing tag
• running before hooks
• running hook=go mod tidy
• setting defaults
• snapshotting
• scm releases
• project name
• loading go mod information
• building binaries
• universal binaries
• creating source archive
• archives
• linux packages
• snapcraft packages
• calculating checksums
• signing artifacts
• signing docker images
• docker images
• docker manifests
• artifactory
• blobs
• homebrew tap formula
• krew plugin manifest
• gofish fish food cookbook
• scoop manifests
• discord
• reddit
• slack
• teams
• twitter
• smtp
• mattermost
• milestones
• linkedin
• telegram
• checking ./dist
• --rm-dist is set, cleaning it up
• loading go mod information
• writing effective config file
• writing config=dist/config.yaml
• generating changelog
• writing changelog=dist/CHANGELOG.md
• building binaries
• building binary=/workspaces/go-goreleaser-drone-example/crimp-city/dist/crimp-city_linux_amd64/crimp-city
• archives
• creating archive=dist/crimp-city_0.1_Linux_x86_64.tar.gz
• calculating checksums
• checksumming file=crimp-city_0.1_Linux_x86_64.tar.gz
• publishing
• scm releases
• creating or updating release repo= tag=v0.1
• Gitea release created id=3
• uploading to release file=dist/checksums.txt name=checksums.txt
• uploading to release file=dist/crimp-city_0.1_Linux_x86_64.tar.gz name=crimp-city_0.1_Linux_x86_64.tar.gz
• announcing
• release succeeded after 1.44s
Great success. If you go browse to the releases page for your repo1, you’ll see a new release, including:
- a changelog of all the commits
- zipped archives of the source code
- a zipped copy of the
crimp-city
binary - a
checksums.txt
so that people can confirm their copy of the downloaded binary is legitimate.
How good is that? And you remember how we had the version embedded in the binary output? Yep, that’s using the git tag we set.
$ ./dist/crimp-city_linux_amd64/crimp-city
█░█ █▀▀ █░░ █░░ █▀█ █░█░█ █▀█ █▀█ █░░ █▀▄
█▀█ ██▄ █▄▄ █▄▄ █▄█ ▀▄▀▄▀ █▄█ █▀▄ █▄▄ █▄▀ version 0.1
Nice. Alright, that’s all for now. Next time we’ll get Drone CI to automatically create a release for us when we push a tag to Gitea.
-
Something like http://gitea:3000/gitea/crimp-city/releases ↩︎