Skip to content

Commit

Permalink
turbobob.json: add description, website, documentation and mo…
Browse files Browse the repository at this point in the history
…ve `project_emoji_icon`

these also get published as OCI-compliant metadata

fix annotations for buildx
  • Loading branch information
joonas-fi committed Aug 27, 2024
1 parent dd2ca4e commit 335cbd8
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 14 deletions.
14 changes: 13 additions & 1 deletion cmd/bob/bobfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,24 @@ type Bobfile struct {
FileDescriptionBoilerplate string `json:"for_description_of_this_file_see"`
VersionMajor int `json:"version_major"`
ProjectName string `json:"project_name"`
ProjectEmojiIcon string `json:"project_emoji_icon,omitempty"` // to quickly differentiate projects in e.g. workspace switcher
Meta ProjectMetadata `json:"meta,omitempty"`
Builders []BuilderSpec `json:"builders"`
DockerImages []DockerImageSpec `json:"docker_images,omitempty"`
Subrepos []SubrepoSpec `json:"subrepos,omitempty"`
OsArches *OsArchesSpec `json:"os_arches,omitempty"`
Experiments experiments `json:"experiments_i_consent_to_breakage,omitempty"`
Deprecated1 string `json:"project_emoji_icon,omitempty"` // moved to `ProjectMetadata`
}

func (b Bobfile) ProjectEmojiIcon() string {
return firstNonEmpty(b.Meta.ProjectEmojiIcon, b.Deprecated1)
}

type ProjectMetadata struct {
Description string `json:"description,omitempty"` // what this project is used for
Website string `json:"website,omitempty"` // URL of homepage or such
Documentation string `json:"documentation,omitempty"` // URL of documentation website
ProjectEmojiIcon string `json:"project_emoji_icon,omitempty"` // to quickly differentiate projects in e.g. workspace switcher
}

// when experiments are removed or graduated to production, they will be removed from here
Expand Down
47 changes: 36 additions & 11 deletions cmd/bob/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,19 +135,39 @@ func buildAndPushOneDockerImage(dockerImage DockerImageSpec, buildCtx *BuildCont
// that non-default branch builds are dev/experimental builds.
shouldTagLatest := dockerImage.TagLatest && buildCtx.IsDefaultBranch

labelArgs := []string{
"--label=org.opencontainers.image.created=" + time.Now().UTC().Format(time.RFC3339),
"--label=org.opencontainers.image.revision=" + buildCtx.RevisionId.RevisionId,
"--label=org.opencontainers.image.version=" + buildCtx.RevisionId.FriendlyRevisionId,
annotationsKeyValues := []string{} // items look like "title=foobar"

// annotationsAs("--annotation=") => ["--annotation=title=foobar"]
annotationsAs := func(argPrefix string) []string {
argified := []string{}
for _, annotation := range annotationsKeyValues {
// "title=foobar" => "--annotation=title=foobar"
argified = append(argified, argPrefix+annotation)
}
return argified
}

if buildCtx.RepositoryURL != "" {
// "URL to get source code for building the image"
labelArgs = append(labelArgs, "--label=org.opencontainers.image.source="+buildCtx.RepositoryURL)
// "URL to find more information on the image"
labelArgs = append(labelArgs, "--label=org.opencontainers.image.url="+buildCtx.RepositoryURL)
annotate := func(key string, value string) {
if value == "" {
return
}

annotationsKeyValues = append(annotationsKeyValues, fmt.Sprintf("%s=%s", key, value))
}

annotate("org.opencontainers.image.title", buildCtx.Bobfile.ProjectName)
annotate("org.opencontainers.image.created", time.Now().UTC().Format(time.RFC3339))
annotate("org.opencontainers.image.revision", buildCtx.RevisionId.RevisionId)
annotate("org.opencontainers.image.version", buildCtx.RevisionId.FriendlyRevisionId)
annotate("org.opencontainers.image.description", buildCtx.Bobfile.Meta.Description)

// "URL to get source code for building the image"
annotate("org.opencontainers.image.source", buildCtx.RepositoryURL)
// "URL to find more information on the image"
annotate("org.opencontainers.image.url", firstNonEmpty(buildCtx.Bobfile.Meta.Website, buildCtx.RepositoryURL))
// "URL to get documentation on the image"
annotate("org.opencontainers.image.documentation", firstNonEmpty(buildCtx.Bobfile.Meta.Documentation, buildCtx.RepositoryURL))

// "" => "."
// "Dockerfile" => "."
// "subdir/Dockerfile" => "subdir"
Expand All @@ -170,7 +190,11 @@ func buildAndPushOneDockerImage(dockerImage DockerImageSpec, buildCtx *BuildCont
"--tag=" + tag,
}

args = append(args, labelArgs...)
// https://docs.docker.com/reference/cli/docker/buildx/build/#annotation
// annotate both the image index and the image manifest.
// if we don't specify type of annotation, only the image manifest is annotated.
// for example GitHub packages UI only shows annotations from OCI image index.
args = append(args, annotationsAs("--annotation=index,manifest:")...)

if shouldTagLatest {
args = append(args, "--tag="+tagLatest)
Expand All @@ -192,7 +216,8 @@ func buildAndPushOneDockerImage(dockerImage DockerImageSpec, buildCtx *BuildCont
"build",
"--file", dockerfilePath,
"--tag", tag}
dockerBuildArgs = append(dockerBuildArgs, labelArgs...)
// `$ docker build ...` doesn't have annotation support. we have to use labels.
dockerBuildArgs = append(dockerBuildArgs, annotationsAs("--label=")...)
dockerBuildArgs = append(dockerBuildArgs, buildContextDir)

//nolint:gosec // ok
Expand Down
4 changes: 2 additions & 2 deletions cmd/bob/workspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ func workspaceRenameToSelectedProject() error {
}

nameWithMaybeIcon := func() string {
if bobfile.ProjectEmojiIcon != "" && userConfig.WindowManagerShowProjectEmojiIcons {
return fmt.Sprintf("%s %s", bobfile.ProjectEmojiIcon, bobfile.ProjectName)
if projectEmojiIcon := bobfile.ProjectEmojiIcon(); projectEmojiIcon != "" && userConfig.WindowManagerShowProjectEmojiIcons {
return fmt.Sprintf("%s %s", projectEmojiIcon, bobfile.ProjectName)
} else {
return bobfile.ProjectName
}
Expand Down

1 comment on commit 335cbd8

@joonas-fi
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixes #46

Please sign in to comment.