Skip to content

Commit

Permalink
Look up git metadata via GitHub env vars when available
Browse files Browse the repository at this point in the history
and fall back to `git` operations otherwise. This also changes the way
that a `git` repo is detected to use `git` itself instead of checking
for `.git` directory existence.

(linked to internal issue PLAT-228)
  • Loading branch information
meatballhat committed Oct 3, 2024
1 parent cfa064a commit 865780a
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 29 deletions.
79 changes: 50 additions & 29 deletions pkg/image/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package image

import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"os"
"os/exec"
"path"
"strings"
"time"

"github.com/getkin/kin-openapi/openapi3"
"github.com/google/go-containerregistry/pkg/name"
Expand All @@ -25,6 +28,8 @@ const weightsManifestPath = ".cog/cache/weights_manifest.json"
const bundledSchemaFile = ".cog/openapi_schema.json"
const bundledSchemaPy = ".cog/schema.py"

var errGit = errors.New("git error")

// Build a Cog model from a config
//
// This is separated out from docker.Build(), so that can be as close as possible to the behavior of 'docker build'.
Expand Down Expand Up @@ -206,18 +211,16 @@ func Build(cfg *config.Config, dir, imageName string, secrets []string, noCache,
labels[global.LabelNamespace+"cog-base-image-last-layer-idx"] = fmt.Sprintf("%d", lastLayerIndex)
}

if isGitRepo(dir) {
if commit, err := gitHead(dir); commit != "" && err == nil {
labels["org.opencontainers.image.revision"] = commit
} else {
console.Info("Unable to determine Git commit")
}
if commit, err := gitHead(dir); commit != "" && err == nil {
labels["org.opencontainers.image.revision"] = commit
} else {
console.Info("Unable to determine Git commit")
}

if tag, err := gitTag(dir); tag != "" && err == nil {
labels["org.opencontainers.image.version"] = tag
} else {
console.Info("Unable to determine Git tag")
}
if tag, err := gitTag(dir); tag != "" && err == nil {
labels["org.opencontainers.image.version"] = tag
} else {
console.Info("Unable to determine Git tag")
}

if err := docker.BuildAddLabelsAndSchemaToImage(imageName, labels, bundledSchemaFile, bundledSchemaPy); err != nil {
Expand Down Expand Up @@ -257,38 +260,56 @@ func BuildBase(cfg *config.Config, dir string, useCudaBaseImage string, useCogBa
return imageName, nil
}

func isGitRepo(dir string) bool {
if _, err := os.Stat(path.Join(dir, ".git")); os.IsNotExist(err) {
func isGitWorkTree(dir string) bool {
ctx, cancel := context.WithTimeout(context.TODO(), 1*time.Second)
defer cancel()

out, err := exec.CommandContext(ctx, "git", "-C", dir, "rev-parse", "--is-inside-work-tree").Output()
if err != nil {
return false
}

return true
return strings.TrimSpace(string(out)) == "true"
}

func gitHead(dir string) (string, error) {
cmd := exec.Command("git", "rev-parse", "HEAD")
cmd.Dir = dir
out, err := cmd.Output()
if err != nil {
return "", err
if v, ok := os.LookupEnv("GITHUB_SHA"); ok {
return v, nil
}

commit := string(bytes.TrimSpace(out))
if isGitWorkTree(dir) {
ctx, cancel := context.WithTimeout(context.TODO(), 1*time.Second)
defer cancel()

return commit, nil
out, err := exec.CommandContext(ctx, "git", "-C", dir, "rev-parse", "HEAD").Output()
if err != nil {
return "", err
}

return string(bytes.TrimSpace(out)), nil
}

return "", fmt.Errorf("Failed to find HEAD commit: %w", errGit)
}

func gitTag(dir string) (string, error) {
cmd := exec.Command("git", "describe", "--tags", "--dirty")
cmd.Dir = dir
out, err := cmd.Output()
if err != nil {
return "", err
if v, ok := os.LookupEnv("GITHUB_REF_NAME"); ok {
return v, nil
}

tag := string(bytes.TrimSpace(out))
if isGitWorkTree(dir) {
ctx, cancel := context.WithTimeout(context.TODO(), 1*time.Second)
defer cancel()

out, err := exec.CommandContext(ctx, "git", "-C", dir, "describe", "--tags", "--dirty").Output()
if err != nil {
return "", err
}

return string(bytes.TrimSpace(out)), nil
}

return tag, nil
return "", fmt.Errorf("Failed to find ref name: %w", errGit)
}

func buildWeightsImage(dir, dockerfileContents, imageName string, secrets []string, noCache bool, progressOutput string) error {
Expand Down
65 changes: 65 additions & 0 deletions pkg/image/build_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package image

import (
"os/exec"
"testing"

"github.com/stretchr/testify/require"
)

func setupGitWorkTree(t *testing.T) string {
r := require.New(t)

tmp := t.TempDir()

r.NoError(exec.Command("git", "init", tmp).Run())
r.NoError(exec.Command("git", "-C", tmp, "commit", "--allow-empty", "-m", "walrus").Run())
r.NoError(exec.Command("git", "-C", tmp, "tag", "-a", "v0.0.1+walrus", "-m", "walrus time").Run())

return tmp
}

func TestIsGitWorkTree(t *testing.T) {
r := require.New(t)

r.False(isGitWorkTree("/dev/null"))
r.True(isGitWorkTree(setupGitWorkTree(t)))
}

func TestGitHead(t *testing.T) {
r := require.New(t)
tmp := setupGitWorkTree(t)

head, err := gitHead(tmp)
r.NoError(err)
r.NotEqual("", head)

head, err = gitHead("/dev/null")
r.Error(err)
r.Equal("", head)

t.Setenv("GITHUB_SHA", "fafafaf")

head, err = gitHead("/dev/null")
r.NoError(err)
r.Equal("fafafaf", head)
}

func TestGitTag(t *testing.T) {
r := require.New(t)
tmp := setupGitWorkTree(t)

tag, err := gitTag(tmp)
r.NoError(err)
r.Equal("v0.0.1+walrus", tag)

tag, err = gitTag("/dev/null")
r.Error(err)
r.Equal("", tag)

t.Setenv("GITHUB_REF_NAME", "v0.0.1+manatee")

tag, err = gitTag("/dev/null")
r.NoError(err)
r.Equal("v0.0.1+manatee", tag)
}

0 comments on commit 865780a

Please sign in to comment.