From 5518b36ac83949b24ed0d73d485b64acfb6a6e30 Mon Sep 17 00:00:00 2001 From: Daniel Mikusa Date: Mon, 22 Aug 2022 16:58:02 -0400 Subject: [PATCH] Draft release action to support monoreo Modifies the draft handling code to support a monorepo where buildpack.toml is not at the root of the project. The default is still at the root of the project, but the path is configurable via environment variable. Signed-off-by: Daniel Mikusa --- README.md | 8 +++++-- drafts/drafts.go | 58 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 106a6d7d..d7c4250f 100644 --- a/README.md +++ b/README.md @@ -412,7 +412,9 @@ A Github token is strongly recommended. This is for fetching information from Gi The `package` and `version` entries are required. They are required to indiciate the specific buildpack that will be described. -A mapper will add additional permutations of Github project URIs to try. For example, if you have an image URI of `gcr.io/foo/bar:1.2.3` but the Github project is at `github.com/org/foo-bar` then you can add a mapper of `|foo\/bar|org/foo-bar|` to have `compute-artifact-dependencies` try both. You can specify as many mappers as you want, with each mapper generating a new URI for `compute-artifact-dependencies` to try. It will stop when it hits the first URL that successfully pulls back the `buildpack.toml` file. +A mapper will add additional permutations of Github project URIs to try. For example, if you have an image URI of `gcr.io/foo/bar:1.2.3` but the Github project is at `github.com/org/foo-bar` then you can add a mapper of `|foo\/bar|org/foo-bar|` to have `compute-artifact-dependencies` try both. You can specify as many mappers as you want, with each mapper generating a new URI for `compute-artifact-dependencies` to try. It will stop when it hits the first URL that successfully pulls back the `buildpack.toml` file.Mappers may use regexp capture groups and reference the captured value with `$` (ex: `$1`, `$2`, etc) in the regular expression. + +The location of the `buildpack.toml` file in the Github project is assumed to be at `/buildpack.toml`. If you have a monorepo with multiple buildpacks, you may adjust the location by setting an environment variable in the format `BP_TOML_PATH__=actual/path` where `` and `` are the organization and repo pulled out of the image URI. For example, `gcr.io/foo/bar:1.2.3`. The org is `foo` and the repo is `bar`. A leading `/` is not necessary, nor is `buildpack.toml` on the end. You may omit that to shorten the value and the action will automatically add `/buildpack.toml` to the end. For example, with an org of `vmware-tanzu` and a repo of `function-buildpacks-for-knative` the environment variable would be `BP_TOML_PATH_VMWARE_TANZU_FUNCTION_BUILDPACKS_FOR_KNATIVE='buildpacks/java/buildpack.toml`, which would be the same as `BP_TOML_PATH_VMWARE_TANZU_FUNCTION_BUILDPACKS_FOR_KNATIVE='buildpacks/java` since the trailing `buildpack.toml` is optional. The output is `artifact-reference-description`, which can be referenced by other jobs. @@ -432,7 +434,9 @@ The `draft-release` action is used to augment release notes generated by the `re The `draft-release` action needs to be able to look up and remotely fetch buildpack metadata. It does this by obtaining the `buildpack.toml` file for any dependent buildpacks from Github. This requires mapping the image URI to the Github project URI, which is not always one-to-one. As such, the action supports mappers. -A mapper will add additional permutations of Github project URIs to try. For example, if you have an image URI of `gcr.io/foo/bar:1.2.3` but the Github project is at `github.com/org/foo-bar` then you can add a mapper of `|foo\/bar|org/foo-bar|` to have `draft-release` try both. You can specify as many mappers as you want, with each mapper generating a new URI for `draft-release` to try. It will stop when it hits the first URL that successfully pulls back the `buildpack.toml` file. +A mapper will add additional permutations of Github project URIs to try. For example, if you have an image URI of `gcr.io/foo/bar:1.2.3` but the Github project is at `github.com/org/foo-bar` then you can add a mapper of `|foo\/bar|org/foo-bar|` to have `draft-release` try both. You can specify as many mappers as you want, with each mapper generating a new URI for `draft-release` to try. It will stop when it hits the first URL that successfully pulls back the `buildpack.toml` file. Mappers may use regexp capture groups and reference the captured value with `$` (ex: `$1`, `$2`, etc) in the regular expression. + +The location of the `buildpack.toml` file in the Github project is assumed to be at `/buildpack.toml`. If you have a monorepo with multiple buildpacks, you may adjust the location by setting an environment variable in the format `BP_TOML_PATH__=actual/path` where `` and `` are the organization and repo pulled out of the image URI. For example, `gcr.io/foo/bar:1.2.3`. The org is `foo` and the repo is `bar`. A leading `/` is not necessary, nor is `buildpack.toml` on the end. You may omit that to shorten the value and the action will automatically add `/buildpack.toml` to the end. For example, with an org of `vmware-tanzu` and a repo of `function-buildpacks-for-knative` the environment variable would be `BP_TOML_PATH_VMWARE_TANZU_FUNCTION_BUILDPACKS_FOR_KNATIVE='buildpacks/java/buildpack.toml`, which would be the same as `BP_TOML_PATH_VMWARE_TANZU_FUNCTION_BUILDPACKS_FOR_KNATIVE='buildpacks/java` since the trailing `buildpack.toml` is optional. ```yaml uses: docker://ghcr.io/paketo-buildpacks/actions/draft-release:main diff --git a/drafts/drafts.go b/drafts/drafts.go index 85a47bf7..892f56e6 100644 --- a/drafts/drafts.go +++ b/drafts/drafts.go @@ -348,28 +348,36 @@ func (g GithubBuildpackLoader) LoadBuildpack(imgUri string) (Buildpack, error) { org := parts[1] repo := parts[2] version := parts[3] - if regexp.MustCompile(`\d+\.\d+\.\d+`).MatchString(version) { - version = fmt.Sprintf("v%s", version) - } - tomlBytes, err := g.fetchTOMLFile(org, repo, version, "/buildpack.toml") + paths, err := g.mapBuildpackTOMLPath(org, repo) if err != nil { - var apiErr *github.ErrorResponse - if errors.As(err, &apiErr) && apiErr.Response.StatusCode == 404 { - fmt.Println("skipping 404", apiErr) - continue - } - return Buildpack{}, fmt.Errorf("unable to fetch toml\n%w", err) + return Buildpack{}, fmt.Errorf("unable to map buildpack toml path\n%w", err) } - if len(tomlBytes) > 0 { - bp, err := loadBuildpackTOML(tomlBytes) + if regexp.MustCompile(`^\d+\.\d+\.\d+$`).MatchString(version) { + version = fmt.Sprintf("v%s", version) + } + + for _, path := range paths { + tomlBytes, err := g.fetchTOMLFile(org, repo, version, path) if err != nil { - return Buildpack{}, fmt.Errorf("unable to load buildpack toml from image\n%w", err) + var apiErr *github.ErrorResponse + if errors.As(err, &apiErr) && apiErr.Response.StatusCode == 404 { + fmt.Println("skipping 404", apiErr) + continue + } + return Buildpack{}, fmt.Errorf("unable to fetch toml\n%w", err) } - bp.Info.Version = parts[3] - return *bp, nil + if len(tomlBytes) > 0 { + bp, err := loadBuildpackTOML(tomlBytes) + if err != nil { + return Buildpack{}, fmt.Errorf("unable to load buildpack toml from image\n%w", err) + } + + bp.Info.Version = parts[3] + return *bp, nil + } } } @@ -442,8 +450,26 @@ func (g GithubBuildpackLoader) mapURIs(uri string) ([]string, error) { return possibilities, nil } +func (g GithubBuildpackLoader) mapBuildpackTOMLPath(org, repo string) ([]string, error) { + paths := []string{ + "/buildpack.toml", + } + + org = strings.ToUpper(strings.ReplaceAll(org, "-", "_")) + repo = strings.ToUpper(strings.ReplaceAll(repo, "-", "_")) + + if p, found := os.LookupEnv(fmt.Sprintf("BP_TOML_PATH_%s_%s", org, repo)); found { + if !strings.HasSuffix(p, "/buildpack.toml") { + p = fmt.Sprintf("%s/buildpack.toml", p) + } + return []string{p}, nil + } + + return paths, nil +} + func (g GithubBuildpackLoader) fetchTOMLFile(org, repo, version, path string) ([]byte, error) { - fmt.Println("Fetching from org:", org, "repo:", repo, "version:", version) + fmt.Println("Fetching from org:", org, "repo:", repo, "version:", version, "path:", path) body, _, err := g.GithubClient.Repositories.DownloadContents( context.Background(), org,