github.com/goreleaser/goreleaser@v1.25.1/www/docs/blog/posts/2022-03-26-reproducible-builds.md (about)

     1  ---
     2  date: 2022-03-26
     3  slug: reproducible-builds
     4  categories:
     5    - tutorials
     6  authors:
     7    - caarlos0
     8  ---
     9  
    10  # Reproducible Builds
    11  
    12  GoReleaser can help you, to some extent, to have reproducible builds.
    13  
    14  ![](https://carlosbecker.com/posts/goreleaser-reproducible-buids/c4824165-c6e2-40df-b4b5-8abe443195ce.png)
    15  
    16  <!-- more -->
    17  
    18  ## **What are reproducible builds?**
    19  
    20  According to [Reproducible-Builds.org](https://reproducible-builds.org/docs/definition/):
    21  
    22  > A build is reproducible if given the same source code, build environment and build instructions, any party can recreate bit-by-bit identical copies of all specified artifacts.
    23  
    24  So, things we need to pay attention here are:
    25  
    26  - the source is the same
    27  - the dependencies are the same, in the same versions
    28  - `chtimes` are the same
    29  - build path is the same
    30  - any other tools needed to compile must be the same, in the same versions
    31  
    32  While this might sound complicated, rest assured GoReleaser can help you with most of these items!
    33  
    34  ## **Reproducible Builds with GoReleaser**
    35  
    36  GoReleaser will by default inject a `ldflag` with the current timestamp as `main.date`, which you can use to display build time information. We will want to change that to use some fixed date, for instance, the date of the commit being built.
    37  
    38  To avoid changes from one machine to another, we will also want to use `-trimpath`.
    39  
    40  Finally, we'll want to make sure the repo code haven't changed, e.g., when building a tag, we want to make sure it wasn't deleted and pushed again (i.e., moved).
    41  
    42  We can achieve that with a config that looks like this:
    43  
    44  ```yaml
    45  builds:
    46    - env:
    47        - CGO_ENABLED=0
    48      goos:
    49        - linux
    50        - darwin
    51      goarch:
    52        - amd64
    53        - arm64
    54      mod_timestamp: "{{ .CommitTimestamp }}"
    55      flags:
    56        - -trimpath
    57      ldflags:
    58        - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{ .CommitDate }}
    59  
    60  gomod:
    61    proxy: true
    62  ```
    63  
    64  From now on, we basically only need to ensure the Go version is the same.
    65  
    66  That's out of the scope of GoReleaser's scope, but easy enough to do in GitHub Actions by pinning to a specific version of Go.
    67  
    68  So, there you have it: reproducible Go binary builds with GoReleaser!