mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-04-11 11:42:15 +02:00
docs(blog): import more posts
refs #3503 Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
This commit is contained in:
parent
3779dfd6a6
commit
29d55a74f8
316
www/docs/blog/posts/2022-02-05-cloud-native-storage.md
Normal file
316
www/docs/blog/posts/2022-02-05-cloud-native-storage.md
Normal file
@ -0,0 +1,316 @@
|
||||
---
|
||||
date: 2022-02-05
|
||||
slug: cloud-native-storage
|
||||
categories:
|
||||
- tutorials
|
||||
authors:
|
||||
- dirien
|
||||
---
|
||||
|
||||
# How to use GoReleaser with Cloud Native Storage
|
||||
|
||||
In this tutorial, I want to describe, how quickly we can deploy our release
|
||||
artefacts to a cloud native storage when using GoReleaser.
|
||||
It’s just a few additional lines in your `.goreleaser.yaml`.
|
||||
|
||||
<!-- more -->
|
||||
|
||||
To better show this, I created a little demo and use the storage services of the
|
||||
big three cloud providers: Azure Blob Storage, AWS S3 and Google Cloud Storage.
|
||||
|
||||

|
||||
|
||||
You can use any S3 compatible storage provider too.
|
||||
**GoReleaser** support this too! The most prominent (self-hosted) solution is
|
||||
**MinIO**.
|
||||
|
||||

|
||||
|
||||
## The infrastructure code
|
||||
|
||||
I created a very simple **Terraform** deployment to provision on all three cloud
|
||||
provider their appropriate cloud storage service.
|
||||
It’s a demo, why not?
|
||||
|
||||
You don’t need to use **Terraform** for this, you could use any other means like
|
||||
**Pulumi**, **CLI** or even the **UI**.
|
||||
|
||||
###### `main.tf`
|
||||
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = "4.9.0"
|
||||
}
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = "2.94.0"
|
||||
}
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "3.74.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "azurerm" {
|
||||
features {}
|
||||
}
|
||||
|
||||
provider "google" {
|
||||
credentials = file(var.gcp_auth_file)
|
||||
project = var.gcp_project
|
||||
region = var.gcp_region
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
region = var.aws_region
|
||||
}
|
||||
```
|
||||
|
||||
###### `variables.tf`
|
||||
|
||||
```terraform
|
||||
variable "gcp_project" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "gcp_region" {
|
||||
default = "europe-west6"
|
||||
}
|
||||
|
||||
variable "gcp_zone" {
|
||||
default = "europe-west6-a"
|
||||
}
|
||||
|
||||
variable "gcp_bucket_location" {
|
||||
default = "EU"
|
||||
}
|
||||
|
||||
variable "gcp_auth_file" {
|
||||
default = "./auth.json"
|
||||
description = "Path to the GCP auth file"
|
||||
}
|
||||
|
||||
variable "aws_region" {
|
||||
default = "eu-central-1"
|
||||
}
|
||||
|
||||
variable "azure_location" {
|
||||
default = "West Europe"
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
default = "gorleaser-quickbites"
|
||||
}
|
||||
```
|
||||
|
||||
###### `blob.tf`
|
||||
|
||||
```terraform
|
||||
resource "google_storage_bucket" "goreleaser-gcp-storage-bucket" {
|
||||
name = var.name
|
||||
location = var.gcp_bucket_location
|
||||
force_destroy = true
|
||||
uniform_bucket_level_access = false
|
||||
}
|
||||
resource "google_storage_bucket_access_control" "goreleaser-gcp-storage-bucket-access-control" {
|
||||
bucket = google_storage_bucket.goreleaser-gcp-storage-bucket.name
|
||||
role = "READER"
|
||||
entity = "allUsers"
|
||||
}
|
||||
|
||||
resource "azurerm_resource_group" "goreleaser-azure-resource-group" {
|
||||
name = var.name
|
||||
location = var.azure_location
|
||||
}
|
||||
|
||||
resource "azurerm_storage_account" "goreleaser-azure-storage-account" {
|
||||
name = "gorleaserquickbites"
|
||||
resource_group_name = azurerm_resource_group.goreleaser-azure-resource-group.name
|
||||
location = azurerm_resource_group.goreleaser-azure-resource-group.location
|
||||
account_tier = "Standard"
|
||||
account_replication_type = "LRS"
|
||||
allow_blob_public_access = true
|
||||
network_rules {
|
||||
default_action = "Allow"
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_storage_container" "goreleaser-storage-container" {
|
||||
name = var.name
|
||||
storage_account_name = azurerm_storage_account.goreleaser-azure-storage-account.name
|
||||
container_access_type = "container"
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket" "goreleaser-s3-bucket" {
|
||||
bucket = var.name
|
||||
acl = "public-read"
|
||||
}
|
||||
```
|
||||
|
||||
###### Apply the Terraform script:
|
||||
|
||||
```bash
|
||||
terraform apply -var "gcp_project=xxx"
|
||||
```
|
||||
|
||||
```
|
||||
...
|
||||
azurerm_storage_container.goreleaser-storage-container: Creation complete after 0s [id=https://gorleaserquickbites.blob.core.windows.net/gorleaser-quickbites]
|
||||
|
||||
Apply complete! Resources: 6 added, 0 changed, 0 destroyed.
|
||||
|
||||
Outputs:
|
||||
|
||||
aws-s3-bucket-name = "gorleaser-quickbites"
|
||||
azure-storage-account-key = <sensitive>
|
||||
azure-storage-account-name = "export AZURE_STORAGE_ACCOUNT=gorleaserquickbites"
|
||||
gcp-bucket-url = "gs://gorleaser-quickbites"
|
||||
```
|
||||
|
||||
###### Run this command
|
||||
|
||||
```bash
|
||||
terraform output azure-storage-account-key
|
||||
```
|
||||
|
||||
to get the Azure Storage Account Key, as it is a output field with sensitive data in it.
|
||||
|
||||
```bash
|
||||
export AZURE_STORAGE_KEY=xxxx
|
||||
```
|
||||
|
||||
Now we can add in our `.goreleaser.yaml` the new **blobs** field.
|
||||
Important is here to set the right provider: **gs** (for Google Cloud Storage),
|
||||
**azblob** (for Azure Blob) and **s3** (for AWS S3 or compatible provider)!
|
||||
|
||||
```yaml
|
||||
# This is an example .goreleaser.yml file with some sensible defaults.
|
||||
# Make sure to check the documentation at https://goreleaser.com
|
||||
before:
|
||||
hooks:
|
||||
- go mod tidy
|
||||
builds:
|
||||
- env:
|
||||
- CGO_ENABLED=0
|
||||
goos:
|
||||
- linux
|
||||
- darwin
|
||||
|
||||
release:
|
||||
disable: true
|
||||
---
|
||||
blobs:
|
||||
- provider: gs
|
||||
bucket: gorleaser-quickbites
|
||||
- provider: azblob
|
||||
bucket: gorleaser-quickbites
|
||||
- provider: s3
|
||||
bucket: gorleaser-quickbites
|
||||
region: eu-central-1
|
||||
```
|
||||
|
||||
In this demo, I disabled the **release **section, as I don’t want to upload to
|
||||
GitHub.
|
||||
|
||||
## Authentication
|
||||
|
||||
In terms of authentication the GoReleaser’s blob pipe authentication varies depending upon the blob provider as mentioned below:
|
||||
|
||||
### S3 Provider
|
||||
|
||||
S3 provider support AWS [default credential
|
||||
provider](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials)
|
||||
chain in the following order:
|
||||
|
||||
- Environment variables.
|
||||
- Shared credentials file.
|
||||
- If your application is running on an Amazon EC2 instance, IAM role for Amazon EC2.
|
||||
|
||||
### Azure Blob Provider Currently it supports authentication only
|
||||
|
||||
with [environment variables](https://docs.microsoft.com/en-us/azure/storage/common/storage-azure-cli#set-default-azure-storage-account-environment-variables):
|
||||
|
||||
- AZURE_STORAGE_ACCOUNT
|
||||
- AZURE_STORAGE_KEY or AZURE_STORAGE_SAS_TOKEN
|
||||
|
||||
### GCS
|
||||
|
||||
Provider GCS provider uses [Application Default
|
||||
Credentials](https://cloud.google.com/docs/authentication/production) in the
|
||||
following order:
|
||||
|
||||
- Environment Variable (GOOGLE_APPLICATION_CREDENTIALS)
|
||||
- Default Service Account from the compute instance (Compute Engine, Kubernetes
|
||||
Engine, Cloud function etc).
|
||||
|
||||
## Run GoReleaser
|
||||
|
||||
After configuring we can finally execute **GoReleaser**, in your pipeline code
|
||||
via the command:
|
||||
|
||||
```bash
|
||||
goreleaser release --rm-dist
|
||||
```
|
||||
|
||||
If everything went smooth, you should see a similar output, showing the upload of your artefacts.
|
||||
|
||||
```
|
||||
...
|
||||
• publishing
|
||||
• blobs
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_checksums.txt
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_darwin_amd64.tar.gz
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_linux_arm64.tar.gz
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_darwin_arm64.tar.gz
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_linux_amd64.tar.gz
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_linux_386.tar.gz
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_checksums.txt
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_checksums.txt
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_linux_386.tar.gz
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_linux_amd64.tar.gz
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_linux_arm64.tar.gz
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_linux_amd64.tar.gz
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_darwin_amd64.tar.gz
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_darwin_arm64.tar.gz
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_linux_386.tar.gz
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_linux_arm64.tar.gz
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_darwin_arm64.tar.gz
|
||||
• uploading path=quick-bites/0.1/quick-bites_0.1_darwin_amd64.tar.gz
|
||||
• release succeeded after 22.63s
|
||||
...
|
||||
```
|
||||
|
||||
> One note: The provider fails silently, if your credentials are wrong. You
|
||||
> would still see uploading and release succeeded. Keep this in mind, if the
|
||||
> files are not appearing in the UI. I wasted some time on this. The culprit is
|
||||
> the underlying library GoReleaser is using.
|
||||
|
||||
Let’s check in the consoles of the cloud provider too, If the files are present.
|
||||
|
||||
###### Google Cloud Storage:
|
||||
|
||||

|
||||
|
||||
###### Azure Blob Storage
|
||||
|
||||

|
||||
|
||||
###### AWS S3
|
||||
|
||||

|
||||
|
||||
Looks very good! Now you can share the URLs of the files for further use!
|
||||
|
||||
## Want more Informations?
|
||||
|
||||
If you want to know more about some advanced options, feel free to check out the
|
||||
[official documentation about the blob support in
|
||||
GoReleaser](https://goreleaser.com/customization/blob/)
|
||||
|
||||
And here is the example code: [dirien/quick-bytes](https://github.com/dirien/quick-bites/tree/main/goreleaser-blob)
|
||||
|
||||

|
402
www/docs/blog/posts/2022-02-20-azure-devops.md
Normal file
402
www/docs/blog/posts/2022-02-20-azure-devops.md
Normal file
@ -0,0 +1,402 @@
|
||||
---
|
||||
date: 2022-02-20
|
||||
slug: azure-devops
|
||||
categories:
|
||||
- tutorials
|
||||
authors:
|
||||
- dirien
|
||||
---
|
||||
|
||||
# Use GoReleaser With Azure DevOps
|
||||
|
||||
In this blog article, I want to show how to use **GoReleaser** in **Azure DevOps**.
|
||||
|
||||
<!-- more -->
|
||||
|
||||

|
||||
|
||||
In this blog article, I want to show how to use **GoReleaser** in **Azure
|
||||
DevOps**.
|
||||
|
||||
### But why? Are not everyone using GitHub?
|
||||
|
||||
Exactly, not everyone is using GitHub. Actually, there are many companies who
|
||||
use the Azure Cloud with **Azure DevOps**.
|
||||
|
||||
## What is Azure DevOps?
|
||||
|
||||
**Azure DevOps** provides developer services for allowing teams to plan work,
|
||||
collaborate on code development, and build and deploy applications.
|
||||
|
||||
**Azure DevOps** provides integrated features that you can access through your
|
||||
web browser or IDE client. You can use one or more of the following standalone
|
||||
services based on your business needs:
|
||||
|
||||
- **Azure Repos** provides Git repositories.
|
||||
- **Azure Pipelines** provides build and release services to support continuous
|
||||
integration and delivery of your applications.
|
||||
- **Azure Boards** delivers a suite of Agile tools to support planning and
|
||||
tracking work, code defects, and issues using Kanban and Scrum methods.
|
||||
- **Azure Test Plans** provides several tools to test your apps, including
|
||||
manual/exploratory testing and continuous testing.
|
||||
- **Azure Artifacts** allows teams to share packages such as Maven, npm, NuGet,
|
||||
and more from public and private sources and integrate package sharing into your
|
||||
pipelines.
|
||||
|
||||
## Install GoReleaser Via The Marketplace
|
||||
|
||||

|
||||
|
||||
**GoReleaser** offers a [Plugin via the
|
||||
Marketplace](https://marketplace.visualstudio.com/items?itemName=GoReleaser.goreleaser).
|
||||
The installation itself is done via some clicks in the UI and you are ready to
|
||||
start!
|
||||
|
||||
In your pipeline editor you can lookup the task:
|
||||
|
||||

|
||||
|
||||
And quickly change the default settings to fit with your use case!
|
||||
For example set a specific version or execute certain **GoReleaser** commands.
|
||||
|
||||
See the official docs for more details
|
||||
[https://github.com/goreleaser/goreleaser-azure-devops-extension](https://github.com/goreleaser/goreleaser-azure-devops-extension)
|
||||
|
||||

|
||||
|
||||
## Finally The Demo!
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
version = "0.0.1"
|
||||
commit = "none"
|
||||
date = "none"
|
||||
builtBy = "none"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("Version:\t", version)
|
||||
fmt.Println("Commit:\t\t", commit)
|
||||
fmt.Println("Date:\t\t", date)
|
||||
fmt.Println("Built by:\t", builtBy)
|
||||
}
|
||||
```
|
||||
|
||||
Before we head over to the configure the pipeline, let us create the
|
||||
`.goreleaser.yaml`
|
||||
|
||||
```yaml
|
||||
# This is an example .goreleaser.yml file with some sensible defaults.
|
||||
# Make sure to check the documentation at https://goreleaser.com
|
||||
before:
|
||||
hooks:
|
||||
# You may remove this if you don't use go modules.
|
||||
- go mod tidy
|
||||
builds:
|
||||
- env:
|
||||
- CGO_ENABLED=0
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
goos:
|
||||
- linux
|
||||
- darwin
|
||||
|
||||
project_name: goreleaser-ado
|
||||
|
||||
checksum:
|
||||
name_template: "checksums.txt"
|
||||
|
||||
snapshot:
|
||||
name_template: "{{ incpatch .Version }}-next"
|
||||
|
||||
source:
|
||||
enabled: true
|
||||
|
||||
release:
|
||||
disable: true
|
||||
|
||||
sboms:
|
||||
- artifacts: archive
|
||||
- id: source
|
||||
artifacts: source
|
||||
|
||||
signs:
|
||||
- cmd: cosign
|
||||
certificate: "${artifact}.pem"
|
||||
args:
|
||||
- sign-blob
|
||||
- "-key=cosign.key"
|
||||
- "--output-certificate=${certificate}"
|
||||
- "--output-signature=${signature}"
|
||||
- "${artifact}"
|
||||
artifacts: checksum
|
||||
output: true
|
||||
stdin: "{{ .Env.COSIGN_PASSWORD }}"
|
||||
|
||||
docker_signs:
|
||||
- cmd: cosign
|
||||
artifacts: images
|
||||
output: true
|
||||
args:
|
||||
- "sign"
|
||||
- "-key=cosign.key"
|
||||
- "${artifact}"
|
||||
stdin: "{{ .Env.COSIGN_PASSWORD }}"
|
||||
|
||||
dockers:
|
||||
- image_templates: ["dirien/{{ .ProjectName }}:{{ .Version }}-amd64"]
|
||||
goarch: amd64
|
||||
dockerfile: Dockerfile
|
||||
use: buildx
|
||||
build_flag_templates:
|
||||
- --platform=linux/amd64
|
||||
- image_templates: ["dirien/{{ .ProjectName }}:{{ .Version }}-arm64"]
|
||||
goarch: arm64
|
||||
dockerfile: Dockerfile
|
||||
use: buildx
|
||||
build_flag_templates:
|
||||
- --platform=linux/arm64/v8
|
||||
|
||||
docker_manifests:
|
||||
- name_template: "dirien/{{ .ProjectName }}:{{ .Version }}"
|
||||
image_templates:
|
||||
- "dirien/{{ .ProjectName }}:{{ .Version }}-amd64"
|
||||
- "dirien/{{ .ProjectName }}:{{ .Version }}-arm64"
|
||||
- name_template: "dirien/{{ .ProjectName }}:latest"
|
||||
image_templates:
|
||||
- "dirien/{{ .ProjectName }}:{{ .Version }}-amd64"
|
||||
- "dirien/{{ .ProjectName }}:{{ .Version }}-arm64"
|
||||
```
|
||||
|
||||
Here, we going to create **linux** and **darwin** binary, the corresponding
|
||||
container, create the SBoM with syft and sign everything via cosign.
|
||||
|
||||
> Here is one first important steps: you need to disable the **release** step in
|
||||
> GoReleaser.
|
||||
> Azure DevOps does not work the same way as GitHub what releases concerns.
|
||||
> We handle the upload of the artefacts differently.
|
||||
|
||||
If you need more infos, for the different settings and possibilities inside
|
||||
**GoReleaser**, head over to the official documentation
|
||||
[https://goreleaser.com/intro/](https://goreleaser.com/intro/)
|
||||
|
||||
### Service
|
||||
|
||||
Connection in Azure DevOps As we going to upload the image to Docker Hub, we
|
||||
need to create in **Azure Devops** the Service Connection.
|
||||
|
||||
Go to **Project Settings** and click **Service connections**:
|
||||

|
||||

|
||||
|
||||
Choose **Docker Registry**:
|
||||

|
||||
|
||||
In the detail view, select **Docker Hub **and then enter your details, like
|
||||
**Docker ID**, **Docker Password** and the **Service Connection Name**:
|
||||

|
||||
|
||||
Click **Verify and save**, we will come back to the service connection in our
|
||||
Pipeline code.
|
||||
|
||||
### The Azure Pipeline File
|
||||
|
||||
Now starts the fun part, the creation of the actual Azure Pipeline.
|
||||
If you are completely new to **Azure DevOps** pipeline, I highly suggest to
|
||||
checkout the
|
||||
[docs](https://docs.microsoft.com/en-us/azure/devops/pipelines/create-first-pipeline?view=azure-devops&tabs=java%2Ctfs-2018-2%2Cbrowser)
|
||||
from Microsoft.
|
||||
|
||||
In our example, we going to write the pipeline only as code (there is a
|
||||
deprecated UI only option too! But meh!).
|
||||
|
||||
Azure Pipeline are written in **yaml.**
|
||||
|
||||
```yaml
|
||||
# Starter pipeline
|
||||
# Start with a minimal pipeline that you can customize to build and deploy your code.
|
||||
# Add steps that build, run tests, deploy, and more:
|
||||
# https://aka.ms/yaml
|
||||
|
||||
pr:
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
|
||||
trigger:
|
||||
tags:
|
||||
include:
|
||||
- "*"
|
||||
branches:
|
||||
include:
|
||||
- "*"
|
||||
|
||||
jobs:
|
||||
- job: build
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- task: GoTool@0
|
||||
displayName: "Install Go"
|
||||
inputs:
|
||||
version: "1.17"
|
||||
- task: CmdLine@2
|
||||
displayName: "Build and Test"
|
||||
inputs:
|
||||
script: |
|
||||
go mod tidy
|
||||
go build .
|
||||
- job: release
|
||||
dependsOn: build
|
||||
displayName: Release via GoReleaser
|
||||
condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/'))
|
||||
variables:
|
||||
- group: cosign
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- task: GoTool@0
|
||||
displayName: "Install Go"
|
||||
inputs:
|
||||
version: "1.17"
|
||||
- task: CmdLine@2
|
||||
displayName: "Install Syft"
|
||||
inputs:
|
||||
script: |
|
||||
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
|
||||
- task: CmdLine@2
|
||||
displayName: "Install cosign"
|
||||
inputs:
|
||||
script: |
|
||||
curl -sLO https://github.com/sigstore/cosign/releases/download/v1.5.2/cosign-linux-amd64
|
||||
chmod +x cosign-linux-amd64
|
||||
mv cosign-linux-amd64 /usr/local/bin/cosign
|
||||
- task: Docker@2
|
||||
inputs:
|
||||
containerRegistry: "dirien-docker-hub"
|
||||
command: "login"
|
||||
addPipelineData: false
|
||||
addBaseImageData: false
|
||||
- task: goreleaser@0
|
||||
inputs:
|
||||
version: "latest"
|
||||
distribution: "goreleaser"
|
||||
args: "release --rm-dist"
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: "Copy GoReleaser dist folder to ArtifactStagingDirectory"
|
||||
inputs:
|
||||
Contents: |
|
||||
dist/*.tar.gz
|
||||
dist/*.zip
|
||||
dist/*.txt
|
||||
dist/*.sbom
|
||||
dist/*.sig
|
||||
cosign.pub
|
||||
TargetFolder: "$(Build.ArtifactStagingDirectory)"
|
||||
CleanTargetFolder: true
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: "Publish GoReleaser release artifacts"
|
||||
inputs:
|
||||
ArtifactName: "GoReleaser release"
|
||||
```
|
||||
|
||||
The pipeline consist of two different jobs parts:
|
||||
|
||||
- the **build** job, run every time something changes on any branch or when a
|
||||
pull request gets created. Here we can run our tests, linting, SAST to get
|
||||
quickly feedback.
|
||||
- the **release** job, will run only when a git tag gets created (see the
|
||||
condition tag under the job tag). Creating a git tag is part of the release
|
||||
process. Similar as we do in the GitHub Flow.
|
||||
|
||||
During the release job, we download [Anchore
|
||||
syft](https://github.com/anchore/syft) and
|
||||
[cosign](https://github.com/sigstore/cosign) as we going to need them during the
|
||||
**gorleaser** task.
|
||||
Currently there is no native task for this in **Azure DevOps**. We just use the
|
||||
**CmdLine** task and curl the binaries.
|
||||
|
||||

|
||||
|
||||
It is also important to log into your **Docker Hub** account, via the **Service
|
||||
Connection** we created earlier.
|
||||
The **Docker** task takes care of the actual login.
|
||||
|
||||

|
||||
|
||||
Now we can call our **GoReleaser** task.
|
||||
|
||||

|
||||
|
||||
### Azure Pipeline Secret Library
|
||||
|
||||
For cosign, I use a password, I stored in the Azure Pipeline Library as secret
|
||||
variable.
|
||||
|
||||

|
||||
|
||||
In my pipeline code, I will pass this value as environment variable via the
|
||||
variables tag.
|
||||
|
||||

|
||||
|
||||
In this demo, I am going to publish the release artefacts as build artefacts.
|
||||
|
||||

|
||||
|
||||
The task **CopyFiles** collects some files from the **dist** folder and the
|
||||
cosign public key and **PublishBuildArtifacts** publish them.
|
||||
You will find the artefacts on the pipeline detail
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
Of course, you can use other targets too, like a cloud native storage.
|
||||
|
||||
You can check out the
|
||||
[How to use GoReleaser with Cloud Native
|
||||
Storage](https://blog.goreleaser.com/how-to-use-goreleaser-with-cloud-native-storage-bbc4bee5fe91)
|
||||
post for more details on this subject
|
||||
|
||||
### Release the kraken äh app!
|
||||
|
||||
Head over to **tags** menu and create a new tag in the UI
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
Your pipeline should immediately start to run:
|
||||
|
||||

|
||||
|
||||
And both jobs should run:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
And this is pretty much all of it! As I promised, very easy and straight forward
|
||||
we can implement **GoReleaser** in **Azure DevOps**, similar we would use it in
|
||||
GitHub
|
||||
|
||||

|
||||
|
||||
### Caveat:
|
||||
|
||||
- I use in cosign not the
|
||||
[keyless](https://github.com/sigstore/cosign/blob/main/KEYLESS.md) approach, as
|
||||
I am not sure that it will work for **Azure DevOps**. So I generated a keypair
|
||||
and committed the public and private key into the repository.
|
133
www/docs/blog/posts/2022-03-07-homebrew-gofish.md
Normal file
133
www/docs/blog/posts/2022-03-07-homebrew-gofish.md
Normal file
@ -0,0 +1,133 @@
|
||||
---
|
||||
date: 2022-03-07
|
||||
slug: homebrew-gofish
|
||||
categories:
|
||||
- tutorials
|
||||
authors:
|
||||
- dirien
|
||||
---
|
||||
|
||||
# GoReleaser: How To Distribute Your Binaries With Homebrew Or GoFish
|
||||
|
||||
This article is going to be a quick bite (or drink)! We going to discover, how
|
||||
fast we can create a **Homebrew** or **GoFish** deployment of our binaries with
|
||||
the help of **GoReleaser**.
|
||||
|
||||
<!-- more -->
|
||||
|
||||
But first, let us take a look into the concepts of the two package managers:
|
||||
|
||||
### **Homebrew **🍺
|
||||
|
||||
> The Missing Package Manager for macOS (or Linux)
|
||||
|
||||
This statement is not from me, but from the official
|
||||
[Homebrew](https://brew.sh/) website. **Homebrew** is similar to other package
|
||||
managers, like [apt-get](https://wiki.debian.org/apt-get),
|
||||
[aptitude](https://wiki.debian.org/Aptitude), or
|
||||
[dpkg](https://wiki.debian.org/dpkg). I will not go in this article into the
|
||||
details about **Homebrew**, but some terms are important to understand, as we
|
||||
going to use them in our `.goreleaser.yaml` file:
|
||||
|
||||
**Tap:** A Git repository of packages.
|
||||
|
||||
**Formula**: A software package. When we want to install new programs or
|
||||
libraries, we install a formula.
|
||||
|
||||
### GoFish 🐠
|
||||
|
||||
> GoFish, the Package Manager 🐠
|
||||
|
||||
[GoFish](https://gofi.sh/) is a cross-platform systems package manager, bringing
|
||||
the ease of use of Homebrew to Linux and Windows. Same as with **Homebrew**, I
|
||||
am not going into detail of **GoFish** but we need also here some understanding
|
||||
of the **GoFish** terminology:
|
||||
|
||||
**Rig:** A git repository containing fish food.
|
||||
|
||||
**Food:** The package definition
|
||||
|
||||
### The example code
|
||||
|
||||
For each package manager, you should create its own GitHub repository. You can
|
||||
name it as you please, but i prefer to add the meaning of the repository.
|
||||
|
||||
- **goreleaser-rig** for GoFish
|
||||
- **goreleaser-tap** for Homebrew
|
||||
|
||||
Add following snippet for **GoFish** support, to your existing
|
||||
`.goreleaser.yaml`:
|
||||
|
||||
```yaml
|
||||
rigs:
|
||||
- rig:
|
||||
owner: dirien
|
||||
name: goreleaser-rig
|
||||
homepage: "https://github.com/dirien/quick-bites"
|
||||
description: "Different type of projects, not big enough to warrant a separate repo."
|
||||
license: "Apache License 2.0"
|
||||
```
|
||||
|
||||
And for **Homebrew**, add this little snippet:
|
||||
|
||||
```yaml
|
||||
brews:
|
||||
- tap:
|
||||
owner: dirien
|
||||
name: goreleaser-tap
|
||||
folder: Formula
|
||||
homepage: "https://github.com/dirien/quick-bites"
|
||||
description: "Different type of projects, not big enough to warrant a separate repo."
|
||||
license: "Apache License 2.0"
|
||||
```
|
||||
|
||||
That’s all for now, and as usual with GoReleaser you can head over to the great
|
||||
documentation for more advanced settings:
|
||||
|
||||
> [https://goreleaser.com](https://goreleaser.com/intro/)
|
||||
|
||||
Now run the release process and you will see this in your logs:
|
||||
|
||||
```
|
||||
• homebrew tap formula
|
||||
• pushing formula=Formula/goreleaser-brew-fish.rb repo=dirien/goreleaser-tap
|
||||
• gofish fish food cookbook
|
||||
• pushing food=Food/goreleaser-brew-fish.lua repo=dirien/goreleaser-rig
|
||||
```
|
||||
|
||||
Perfect! Everything works as expected.
|
||||
|
||||
We can check the content on the GitHub UI.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### Installation
|
||||
|
||||
Now we can add the tap and the rig on our clients
|
||||
|
||||
**Homebrew**
|
||||
|
||||
```bash
|
||||
brew tap dirien/goreleaser-tap
|
||||
brew install goreleaser-brew-fish
|
||||
```
|
||||
|
||||
**GoFish**
|
||||
|
||||
```bash
|
||||
gofish rig add https://github.com/dirien/goreleaser-rig
|
||||
gofish install github.com/dirien/goreleaser-rig/goreleaser-brew-fish
|
||||
```
|
||||
|
||||
### The End
|
||||
|
||||
Now you can distribute this tap or rig repositories and everybody can install your projects via this package manager.
|
||||
|
||||

|
||||
|
||||
### The Code
|
||||
|
||||
You can find the demo code in my repository, to see some more details:
|
||||
[dirien/quick-bites](https://github.com/dirien/quick-bites/tree/main/goreleaser-brew-fish).
|
Loading…
x
Reference in New Issue
Block a user