Skip to content

Commit

Permalink
Merge pull request #3932 from deitch/build-args-with-versions
Browse files Browse the repository at this point in the history
include source repo, revision and go package version as build-args
  • Loading branch information
deitch committed Jun 12, 2023
2 parents aad12b5 + de13ee5 commit aab61a1
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 4 deletions.
17 changes: 17 additions & 0 deletions docs/packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,23 @@ linuxkit pkg build --platforms=linux/arm64 --builders linux/arm64=my-remote-arm6

linuxkit will try to build for `linux/arm64` using the context `my-remote-arm64`. Since that context does not exist, you will get an error.

##### Preset build arguments

When building packages, the following build-args automatically are set for you:

* `SOURCE` - the source repository of the package
* `REVISION` - the git commit that was used for the build
* `GOPKGVERSION` - the go package version or pseudo-version per https://go.dev/ref/mod#glos-pseudo-version

Note that the above are set **only** if you do not set them in `build.yaml`. Your settings _always_
override these built-in ones.

To use them, simply address them in your `Dockerfile`:

```dockerfile
ARG SOURCE
```

### Build packages as a maintainer

All official LinuxKit packages are multi-arch manifests and most of
Expand Down
27 changes: 24 additions & 3 deletions src/cmd/linuxkit/pkglib/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,12 +309,23 @@ func (p Pkg) Build(bos ...BuildOpt) error {
if p.git != nil && p.gitRepo != "" {
imageBuildOpts.Labels["org.opencontainers.image.source"] = p.gitRepo
}
if p.git != nil && !p.dirty {
commit, err := p.git.commitHash("HEAD")
var (
gitCommit string
goPkgVersion string
)
if p.git != nil {
if !p.dirty {
gitCommit, err = p.git.commitHash("HEAD")
if err != nil {
return err
}
imageBuildOpts.Labels["org.opencontainers.image.revision"] = gitCommit
}
// get the go version or pseudo-version
goPkgVersion, err = p.git.goPkgVersion()
if err != nil {
return err
}
imageBuildOpts.Labels["org.opencontainers.image.revision"] = commit
}

imageBuildOpts.NetworkMode = "default"
Expand Down Expand Up @@ -342,6 +353,16 @@ func (p Pkg) Build(bos ...BuildOpt) error {
imageBuildOpts.BuildArgs[parts[0]] = &parts[1]
}
}
// add in information about the build process that might be useful
if _, ok := imageBuildOpts.BuildArgs["SOURCE"]; !ok && p.gitRepo != "" {
imageBuildOpts.BuildArgs["SOURCE"] = &p.gitRepo
}
if _, ok := imageBuildOpts.BuildArgs["REVISION"]; !ok && gitCommit != "" {
imageBuildOpts.BuildArgs["REVISION"] = &gitCommit
}
if _, ok := imageBuildOpts.BuildArgs["GOPKGVERSION"]; !ok && goPkgVersion != "" {
imageBuildOpts.BuildArgs["GOPKGVERSION"] = &goPkgVersion
}

// build for each arch and save in the linuxkit cache
for _, platform := range platformsToBuild {
Expand Down
33 changes: 33 additions & 0 deletions src/cmd/linuxkit/pkglib/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,36 @@ func (g git) isDirty(pkg, commit string) (bool, error) {
return false, err
}
}

// goPkgVersion return a version that is compliant with go package versioning.
// This would either be:
//
// - The tag name if the most recent commit is tagged
// - The structure <version>-<count>-<commmit> if the most recent commit is not tagged
//
// See https://go.dev/ref/mod for more information
func (g git) goPkgVersion() (string, error) {
lastSemver, _ := g.commandStdout(nil, "--no-pager", "describe", "--match='v[0-9].[0-9].[0-9]*'", "--abbrev=0", "--tags")
if lastSemver == "" {
lastSemver = "v0.0.0"
}
commitList := "HEAD"
if lastSemver != "v0.0.0" {
commitList = fmt.Sprintf("%s..HEAD", lastSemver)
}
count, err := g.commandStdout(nil, "rev-list", commitList, "--count")
if err != nil {
return "", err
}
version := ""
if count == "0" {
version = lastSemver
} else {
dateCommit, err := g.commandStdout(nil, "--no-pager", "show", "--quiet", "--abbrev=12", "--date=format-local:%Y%m%d%H%M%S", "--format=%cd-%h")
if err != nil {
return "", err
}
version = fmt.Sprintf("%s-%s", lastSemver, dateCommit)
}
return version, nil
}
2 changes: 1 addition & 1 deletion test/cases/000_build/030_build_args/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set -ex
. "${RT_PROJECT_ROOT}/_lib/lib.sh"

# Test code goes here
echo Linuxkig is "$(which linuxkit)"
echo Linuxkit is "$(which linuxkit)"
RESULT="$(2>&1 linuxkit pkg build --force . | grep PASSED)"
echo RESULT="${RESULT}"
echo "${RESULT}" | grep "Build-arg test PASSED"
Expand Down
11 changes: 11 additions & 0 deletions test/cases/000_build/031_fixed_build_args/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM alpine:3.17

ARG SOURCE=FAILED
ARG REVISION=FAILED
ARG GOPKGVERSION=FAILED

RUN echo "printf \"Build-arg test source $SOURCE\\n\"" >> check.sh
RUN echo "printf \"Build-arg test revision $REVISION\\n\"" >> check.sh
RUN echo "printf \"Build-arg test gopkgversion $GOPKGVERSION\\n\"" >> check.sh

ENTRYPOINT ["/bin/sh", "/check.sh"]
5 changes: 5 additions & 0 deletions test/cases/000_build/031_fixed_build_args/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
image: build-args-test
network: true
arches:
- amd64
- arm64
18 changes: 18 additions & 0 deletions test/cases/000_build/031_fixed_build_args/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/sh
# SUMMARY: Check that the build-args are correctly passed to Dockerfiles
# LABELS:
# REPEAT:

set -ex

# Source libraries. Uncomment if needed/defined
#. "${RT_LIB}"
. "${RT_PROJECT_ROOT}/_lib/lib.sh"

# Test code goes here
echo Linuxkit is "$(which linuxkit)"
RESULT="$(2>&1 linuxkit pkg build --force . | grep 'Build-arg test' || echo)"
echo RESULT="${RESULT}"
echo "${RESULT}" | grep -v "FAILED"

exit 0

0 comments on commit aab61a1

Please sign in to comment.