Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Link container images in changelog to GCR #2439

Merged
merged 1 commit into from
Feb 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 32 additions & 4 deletions pkg/notes/document/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,42 @@ func fetchImageMetadata(dir, tag string) (*ImageMetadata, error) {
}

res := ImageMetadata{}
for manifest, architectures := range manifests {

// Link the images to their corresponding Google Cloud container registry
// location.
const linkBase = "https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/"

for manifest, tempArchitectures := range manifests {
imageName := strings.TrimPrefix(manifest, image.ProdRegistry+"/")

architectures := []string{}
for _, architecture := range tempArchitectures {
architectures = append(
architectures,
markdownLink(architecture, linkBase+imageName+"-"+architecture),
)
}

res = append(res, Image{
Name: fmt.Sprintf("%s:%s", manifest, tag),
Name: markdownLink(
fmt.Sprintf("%s:%s", manifest, tag),
linkBase+imageName,
),
Architectures: architectures,
})
}

sort.SliceStable(res, func(i, j int) bool {
return res[i].Name < res[j].Name
})

return &res, nil
}

func markdownLink(text, link string) string {
return fmt.Sprintf("[%s](%s)", text, link)
}

// fileInfo fetches file metadata for files in `dir` matching `patterns`
func fileInfo(dir string, patterns []string, urlPrefix, tag string) ([]File, error) {
var files []File
Expand Down Expand Up @@ -430,7 +456,8 @@ func CreateDownloadsTable(w io.Writer, bucket, tars, images, prevTag, newTag str
}

fmt.Fprintf(w, "# %s\n\n", newTag)
fmt.Fprintf(w, "[Documentation](https://docs.k8s.io)\n\n")
fmt.Fprint(w, markdownLink("Documentation", "https://docs.k8s.io"))
fmt.Fprintf(w, "\n\n")

fmt.Fprintf(w, "## Downloads for %s\n\n", newTag)

Expand All @@ -454,7 +481,8 @@ func CreateDownloadsTable(w io.Writer, bucket, tars, images, prevTag, newTag str
fmt.Fprintln(w, "-------- | -----------")

for _, f := range files[header] {
fmt.Fprintf(w, "[%s](%s) | `%s`\n", f.Name, f.URL, f.Checksum)
fmt.Fprint(w, markdownLink(f.Name, f.URL))
fmt.Fprintf(w, " | `%s`\n", f.Checksum)
}
fmt.Fprintln(w, "")
}
Expand Down
35 changes: 34 additions & 1 deletion pkg/notes/document/document_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package document

import (
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"
Expand All @@ -27,6 +28,7 @@ import (
"k8s.io/release/pkg/notes"
"k8s.io/release/pkg/notes/options"
"k8s.io/release/pkg/release"
"sigs.k8s.io/release-utils/command"
)

func TestFileMetadata(t *testing.T) {
Expand Down Expand Up @@ -256,6 +258,37 @@ func setupTestDir(t *testing.T, dir string) {
filepath.Join(dir, file), []byte{1, 2, 3}, os.FileMode(0o644),
))
}
for _, arch := range []string{"amd64", "arm", "arm64", "ppc64le", "s390x"} {
archDir := filepath.Join(dir, release.ImagesPath, arch)
require.Nil(t, os.MkdirAll(archDir, fs.FileMode(0o755)))

for _, file := range []string{
fmt.Sprintf("conformance-%s.tar", arch),
"kube-apiserver.tar",
"kube-controller-manager.tar",
"kube-proxy.tar",
"kube-scheduler.tar",
} {
repoTagTarball(t,
filepath.Join(archDir, file),
"k8s.gcr.io/"+strings.TrimSuffix(file, ".tar")+":v1.16.0",
)
}
}
}

func repoTagTarball(t *testing.T, path, repoTag string) {
const manifestJSON = "manifest.json"
manifestJSONPath := filepath.Join(filepath.Dir(path), manifestJSON)
require.Nil(t, os.WriteFile(
manifestJSONPath,
[]byte(fmt.Sprintf(`[{"RepoTags": ["%s"]}]`, repoTag)),
os.FileMode(0o644),
))
require.Nil(t, command.NewWithWorkDir(filepath.Dir(path),
"tar", "cf", path, manifestJSON,
).RunSilentSuccess())
require.Nil(t, os.RemoveAll(manifestJSONPath))
}

func TestNew(t *testing.T) {
Expand Down Expand Up @@ -514,7 +547,7 @@ func TestDocument_RenderMarkdownTemplate(t *testing.T) {
}

// When
got, err := doc.RenderMarkdownTemplate(release.ProductionBucket, dir, "", templateSpec)
got, err := doc.RenderMarkdownTemplate(release.ProductionBucket, dir, dir, templateSpec)

// Then
require.NoError(t, err, "Unexpected error.")
Expand Down
15 changes: 13 additions & 2 deletions pkg/notes/document/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ const defaultReleaseNotesTemplate = `
{{- $CurrentRevision := .CurrentRevision -}}
{{- $PreviousRevision := .PreviousRevision -}}

{{if .FileDownloads}}
{{if or .FileDownloads .ImageDownloads}}
## Downloads for {{$CurrentRevision}}

{{- if .FileDownloads -}}
{{- with .FileDownloads.Source }}

### Source Code
Expand Down Expand Up @@ -65,8 +66,18 @@ filename | sha512 hash
-------- | -----------
{{range .}}[{{.Name}}]({{.URL}}) | {{.Checksum}}{{println}}{{end}}
{{end -}}
{{- end -}}

{{if .ImageDownloads}}
{{- with .ImageDownloads -}}
` + ContainerImagesDescription + `
name | architectures
---- | -------------
{{range .}}{{.Name}} | {{ range $i, $a := .Architectures}}{{if $i}}, {{end}}{{$a}}{{end}}{{println}}{{end}}
{{end -}}

{{end -}}
{{end -}}
{{- end -}}
{{with .CVEList -}}
## Important Security Information

Expand Down
14 changes: 14 additions & 0 deletions pkg/notes/document/testdata/document.md.golden
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,20 @@ filename | sha512 hash
[kubernetes-node-linux-s390x.tar.gz](https://dl.k8s.io/v1.16.1/kubernetes-node-linux-s390x.tar.gz) | 27864cc5219a951a7a6e52b8c8dddf6981d098da1658d96258c870b2c88dfbcb51841aea172a28bafa6a79731165584677066045c959ed0f9929688d04defc29
[kubernetes-node-windows-amd64.tar.gz](https://dl.k8s.io/v1.16.1/kubernetes-node-windows-amd64.tar.gz) | 27864cc5219a951a7a6e52b8c8dddf6981d098da1658d96258c870b2c88dfbcb51841aea172a28bafa6a79731165584677066045c959ed0f9929688d04defc29

### Container Images

All container images are available as manifest lists and support the described
architectures. It is also possible to pull a specific architecture directly by
adding the "-$ARCH" suffix to the container image name.

name | architectures
---- | -------------
[k8s.gcr.io/conformance:v1.16.1](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/conformance) | [amd64](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/conformance-amd64), [arm](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/conformance-arm), [arm64](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/conformance-arm64), [ppc64le](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/conformance-ppc64le), [s390x](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/conformance-s390x)
[k8s.gcr.io/kube-apiserver:v1.16.1](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-apiserver) | [amd64](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-apiserver-amd64), [arm](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-apiserver-arm), [arm64](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-apiserver-arm64), [ppc64le](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-apiserver-ppc64le), [s390x](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-apiserver-s390x)
[k8s.gcr.io/kube-controller-manager:v1.16.1](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-controller-manager) | [amd64](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-controller-manager-amd64), [arm](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-controller-manager-arm), [arm64](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-controller-manager-arm64), [ppc64le](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-controller-manager-ppc64le), [s390x](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-controller-manager-s390x)
[k8s.gcr.io/kube-proxy:v1.16.1](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-proxy) | [amd64](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-proxy-amd64), [arm](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-proxy-arm), [arm64](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-proxy-arm64), [ppc64le](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-proxy-ppc64le), [s390x](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-proxy-s390x)
[k8s.gcr.io/kube-scheduler:v1.16.1](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-scheduler) | [amd64](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-scheduler-amd64), [arm](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-scheduler-arm), [arm64](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-scheduler-arm64), [ppc64le](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-scheduler-ppc64le), [s390x](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/kube-scheduler-s390x)

## Urgent Upgrade Notes

### (No, really, you MUST read this before you upgrade)
Expand Down