1# packages.yml
2#
3# packages.yml defines all the packages we are able to build for a single commit
4# in this repo. A package means a single zip file containing the executable binary,
5# and optionally other files if needed.
6#
7# packages.yml is a convenience file for the human management of large numbers of
8# alternate packages, allowing default and templated values. We generate another
9# artifact from this one, called packages.lock which contains the fully expanded set
10# of package and layer specs. This fully expanded file is in turn used to drive the
11# build process, and as data for templating CI config.
12
13# config contains packagespec config for this repo.
14config:
15  # product-repo is important to CI providers.
16  product-repo:          https://github.com/hashicorp/vault.git
17  release-repo:          https://github.com/hashicorp/vault-release.git
18  # product-id is used by external systems to identify this product.
19  # It can be any unique name, but a golang import path is ideal.
20  product-id:            github.com/hashicorp/vault
21  circleci-project-slug: gh/hashicorp/vault
22  circleci-host:         circleci.com
23  on-publish:            create-github-release
24
25# inputs are a set of environment variables that may affect the set of bytes produced
26# for a given package. Note that a package is a zip file containing the binary, so
27# the name of the binary does affect the package's bytes.
28inputs:
29
30  # defaults contains default input values for each package.
31  # These values may be overridden on a per-package basis in the packages section.
32  defaults:
33
34    # PRODUCT_VERSION is the version of this product. Usually, this should be left
35    # as 0.0.0-snapshot. When we build a release candidate, this is overridden in
36    # a one-off fashion to produce that build.
37    # This should be used in the PACKAGE_NAME template.
38    PRODUCT_VERSION: 0.0.0-snapshot
39
40    # GO_VERSION is the version of the Go toolchain to use to compile this package.
41    GO_VERSION: 1.16.7
42
43    # YARN_VERSION is the version of Yarn to install for the UI layer.
44    YARN_VERSION: 1.19.1-1
45
46    # Standard golang environment variables, passed to the 'go build' command.
47    # You can use any standard environment variables here, any that you omit
48    # will be ommitted from the go build command too, meaning to use the system
49    # default in the build container.
50    CGO_ENABLED: 0
51    GO111MODULE: "off"
52
53  # templates contain golang template strings. Each of these is rendered per package
54  # using that packages values (including any default values), and then added to that
55  # package.
56  # Note that templates MAY NOT refer to each other, but may refer to any default or
57  # package-specific inputs.
58  templates:
59
60    # BINARY_NAME is the name of the executable binary we compile and package.
61    # It is the name users will use on the CLI to invoke the product.
62    BINARY_NAME: 'vault{{if eq .GOOS "windows"}}.exe{{end}}'
63
64    # PRODUCT_VERSION_MMP is just the major.minor.prerelease fields of the PRODUCT_VERSION.
65    # Think semantic versioning (semver), although we do not version our binaries
66    # using semver.
67    PRODUCT_VERSION_MMP: >-
68      {{with .PRODUCT_VERSION | strings.SplitN "-" 2}}{{index . 0}}{{end}}
69    # PRODUCT_VERSION_PRE is just the prerelease field of the product version (i.e. the bit
70    # after any -, if there is one.
71    PRODUCT_VERSION_PRE: >-
72      {{with .PRODUCT_VERSION | strings.SplitN "-" 2}}{{if gt (len .) 1}}{{index . 1}}{{else}}"''"{{end}}{{end}}
73
74# build-command is a templated bash script to be run in the final builder container
75# to produce the package. It may refer to any of the inputs, including rendered templates,
76# but not meta data.
77#
78# The build command is passed 3 environment variables, in addition to all those specified as inputs.
79#
80#   - PACKAGE_SOURCE_ID       The source ID (usually the git commit SHA, unless build is dirty)
81#   - OUTPUT_DIR              Directory to write the executable and zip file to (will exist already)
82#   - PACKAGE_ZIP_NAME        The name of the package zip file to create (relative to OUTPUT_DIR)
83#
84# NOTE: You MUST NOT use single quotes in the build command, because at present we do no escaping.
85build-command: VERSION_PKG_PATH=github.com/hashicorp/vault/sdk/version;
86  GO111MODULE=on
87  go build -v
88    -tags ui
89    -ldflags "
90      -X $VERSION_PKG_PATH.GitCommit=$PACKAGE_SOURCE_ID
91      -X $VERSION_PKG_PATH.Version={{.PRODUCT_VERSION_MMP}}
92      -X $VERSION_PKG_PATH.VersionPrerelease={{.PRODUCT_VERSION_PRE}}"
93    -o $OUTPUT_DIR/{{.BINARY_NAME}}
94  && cd $OUTPUT_DIR && zip $PACKAGE_ZIP_NAME {{.BINARY_NAME}}
95
96# packages is the full set of packages we are able to build based on a single commit
97# in this repo. Each package is a map where the keys are the names of environment
98# variables provided to each build (think 'go build' invocation). Each package is
99# expanded by first filling in any unspecified variables with those from defaults,
100# and then rendering each template and adding the result to the map.
101# Each package must result in a unique PACKAGE_NAME.
102#
103# The fully expanded set of packages are written to packages.lock. That file
104# is a useful data source for building CI/CD pipelines.
105packages:
106  - inputs: { GOOS: darwin, GOARCH: amd64 }
107  - inputs: { GOOS: darwin, GOARCH: arm64 }
108  - inputs: { GOOS: freebsd, GOARCH: 386 }
109  - inputs: { GOOS: freebsd, GOARCH: amd64 }
110  - inputs: { GOOS: freebsd, GOARCH: arm }
111  - inputs: { GOOS: linux, GOARCH: 386 }
112  - inputs: { GOOS: linux, GOARCH: amd64 }
113  - inputs: { GOOS: linux, GOARCH: arm }
114  - inputs: { GOOS: linux, GOARCH: arm64 }
115  - inputs: { GOOS: netbsd, GOARCH: 386 }
116  - inputs: { GOOS: netbsd, GOARCH: amd64 }
117  - inputs: { GOOS: openbsd, GOARCH: 386 }
118  - inputs: { GOOS: openbsd, GOARCH: amd64 }
119  - inputs: { GOOS: solaris, GOARCH: amd64 }
120  - inputs: { GOOS: windows, GOARCH: 386 }
121  - inputs: { GOOS: windows, GOARCH: amd64 }
122
123# meta defines additional custom metadata about packages. This metadata does not
124# participate in the PACKAGE_SPEC_ID and so changing it does not directly change cache
125# keys for layers or packages. In addition, metadata may not be overridden per-package
126# and is not available to input or layer dockerfile templates.
127meta:
128
129  defaults:
130    # No default metadata.
131
132  templates:
133    # BUILD_JOB_NAME is the name of a job to build this package in CI. Care must be
134    # taken that it is both unique within this set of packages, as well as compatible
135    # with the CI system's naming conventions.
136    BUILD_JOB_NAME: >-
137      {{.GOOS}}_{{.GOARCH}}_package
138
139    # BUNDLE_NAME is used in archive filenames, as well as by downstream processes.
140    BUNDLE_NAME: "vault_{{.PRODUCT_VERSION}}"
141
142# package-aliases are a set of paths by which each package may be known, they are
143# templates which may refer to any input or meta field defined in this file.
144# Package aliases must be unique across all packages defined in this file.
145# If any package-alias renders to empty, it is ignored. You can use this
146# to produce aliases selectively depending on the package.
147#
148# Package aliases count as meta data because they do not affect the bytes produced
149# per package.
150#
151# We use package aliases to give human-readable names to packages, and to arrange
152# them in a directory hierarchy ready for further processing and distribution.
153# Each alias is written as a relative symbolic link in .buildcache/packages/by-alias.
154#
155# At least one alias must render to a nonempty string.
156package-aliases:
157  - type: local
158    template: >-
159      {{.BUNDLE_NAME}}_{{.GOOS}}_{{.GOARCH}}.zip
160  # public-hc-releases is the path to use for upload to releases.hashicorp.com
161  # it is empty if this package is not public (empty aliases are ignored).
162  - type: public-hc-releases
163    template: >-
164      vault/{{.BUNDLE_NAME}}/{{.BUNDLE_NAME}}_{{.GOOS}}_{{.GOARCH}}.zip
165
166# Layers determines the build layers, which are individually cacheable layers
167# in a linear build. Each layer contains a Dockerfile. All the layers
168# together produce the final builder image used to compile binaries.
169#
170# The partial Dockerfiles may contain references to any of the inputs
171# including rendered input templates, but may not reference meta data.
172# These Dockerfiles, once rendered, count as inputs and affect the
173# package spec ID of each package.
174#
175# The order of layers is significant. The first layer must have a FROM line, and
176# forms the base image. Each subsequent layer begins from the previous one.
177#
178# You can control cacheability by careful use of variables and ordering.
179# Try to group things which change infrequently towards the top, and
180# things which change more frequently towards the bottom.
181#
182# If there are things you want to cache that vary between packages defined in
183# this file, put them last so that the greater bulk of work can be shared.
184#
185# NOTE: At present, changing the names and/or adding/removing layers may
186# require updating the CI template file at .circleci/config/@build-release.yml.tpl
187# which references some of these layers by name.
188base-image: "debian@sha256:68f4e2259032a4e6f5035804e64438b52af8dd5889528b305b9059183ea4cd2a"
189layers:
190  - name: base
191    dockerfile: |-
192      RUN apt-get update -y && apt-get install --no-install-recommends -y -q \
193                               curl \
194                               zip \
195                               build-essential \
196                               gcc-multilib \
197                               g++-multilib \
198                               ca-certificates \
199                               git mercurial bzr \
200                               gnupg \
201                               libltdl-dev \
202                               libltdl7 \
203      						             bash \
204                            && rm -rf /var/lib/apt/lists/*
205  - name: install-go
206    dockerfile: |-
207      ENV GOPATH /gopath
208      ENV GOROOT /goroot
209      RUN mkdir $GOROOT && mkdir $GOPATH
210      RUN curl https://storage.googleapis.com/golang/go{{.GO_VERSION}}.linux-amd64.tar.gz \
211                 | tar xzf - -C $GOROOT --strip-components=1
212      ENV PATH $GOROOT/bin:$GOPATH/bin:$PATH
213  - name: install-go-tools
214    dockerfile: |
215      ENV GO111MODULE=off
216      RUN go get golang.org/x/tools/cmd/goimports
217      RUN go get github.com/hashicorp/go-bindata
218      RUN go get github.com/hashicorp/go-bindata/go-bindata
219      RUN go get github.com/elazarl/go-bindata-assetfs
220      RUN go get github.com/elazarl/go-bindata-assetfs/go-bindata-assetfs
221  - name: set-workdir
222    dockerfile: |
223      ENV REPO=github.com/hashicorp/vault
224      ENV DIR=$GOPATH/src/$REPO
225      RUN mkdir -p $DIR
226      WORKDIR $DIR
227  - name: install-yarn
228    dockerfile: |-
229      RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
230      RUN curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
231      RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
232      RUN apt-get update -y && apt-get install -y -q nodejs yarn={{.YARN_VERSION}} \
233                            && rm -rf /var/lib/apt/lists/*
234  - name: ui-dependencies
235    source-include: ui/package.json ui/yarn.lock
236    dockerfile: |-
237      RUN cd ui && yarn install
238      RUN cd ui && npm rebuild node-sass
239  - name: build-ui
240    source-include: ui/
241    dockerfile: |-
242      RUN { while true; do sleep 30; echo keepalive; done; } & cd ui && yarn --verbose run build
243  - name: build-static-assets
244    source-include: Makefile
245    dockerfile: |-
246      RUN go-bindata-assetfs -o bindata_assetfs.go -pkg http -prefix pkg -modtime 1480000000 -tags ui ./pkg/web_ui/...
247      RUN mkdir -p http && mv bindata_assetfs.go http/
248      RUN goimports -w http/bindata_assetfs.go
249  - name: go-modules
250    source-include: "go.mod go.sum */go.mod */go.sum"
251    dockerfile: |
252      ENV GO111MODULE=on
253      RUN go mod download
254  # The final layer must contain all the source code we've not yet included.
255  - name: copy-source
256    source-include: "*.go"
257