Skip to content

Commit

Permalink
Merge pull request #484 from paketo-buildpacks/bump-cpe-purl
Browse files Browse the repository at this point in the history
Allow update tasks to bump version numbers in CPE & PURL
  • Loading branch information
Daniel Mikusa authored Dec 3, 2021
2 parents 76bf90a + 4b2a0f0 commit 016cfbd
Show file tree
Hide file tree
Showing 15 changed files with 184 additions and 46 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ dependencies:
- name: JRE 11
id: jre
version_pattern: "11\\.[\\d]+\\.[\\d]+"
purl_pattern: "version-11\\.[\\d]+\\.[\\d]+"
cpe_pattern: "patch[\\d]+"
uses: docker://ghcr.io/paketo-buildpacks/actions/adoptium-dependency:main
with:
implementation: hotspot
Expand All @@ -184,7 +186,7 @@ dependencies:

* [Example `update-*.yml`](https://github.com/paketo-buildpacks/adoptium/blob/main/.github/workflows/update-jre-11.yml)

`dependencies` is a list of objects that define how dependencies are detected and updated by describing an optional `name` (defaults to `id`), `id` that matches a `buildpack.toml` defined dependency id, an optional `version_pattern` that defines which dependency with a given `id` to update, a `uses` to define which GitHub Action to use to find the next version, and a `with` used to configure the GitHub action to use to find the next version. If defined, each object will create an `update` workflow that is responsible for detecting a new version, updating `buildpack.toml` and opening a PR to include the change in the repository, if appropriate.
`dependencies` is a list of objects that define how dependencies are detected and updated by describing an optional `name` (defaults to `id`), `id` that matches a `buildpack.toml` defined dependency id, an optional `version_pattern` that defines which dependency with a given `id` to update, optional `purl_pattern` and `cpe_pattern` values which allow you to provide alternative patterns for updating the CPEs and PURL (they default to the version pattern), a `uses` to define which GitHub Action to use to find the next version, and a `with` used to configure the GitHub action to use to find the next version. If defined, each object will create an `update` workflow that is responsible for detecting a new version, updating `buildpack.toml` and opening a PR to include the change in the repository, if appropriate.

#### `test`
```yaml
Expand Down
21 changes: 21 additions & 0 deletions actions/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"os"
"regexp"
"strings"

"github.com/Masterminds/semver/v3"
)

type Inputs map[string]string
Expand All @@ -41,6 +43,25 @@ func NewInputs() Inputs {

type Outputs map[string]string

func NewOutputs(uri string, latestVersion *semver.Version, additionalOutputs Outputs, mods ...RequestModifierFunc) (Outputs, error) {
sha256, err := SHA256FromURI(uri, mods...)
if err != nil {
return nil, fmt.Errorf("unable to calculate sha256\n%w", err)
}

outputs := Outputs{
"sha256": sha256,
"uri": uri,
"version": fmt.Sprintf("%d.%d.%d", latestVersion.Major(), latestVersion.Minor(), latestVersion.Patch()),
}

for k, v := range additionalOutputs {
outputs[k] = v
}

return outputs, nil
}

func (o Outputs) Write(writer io.Writer) {
for k, v := range o {
_, _ = fmt.Fprintf(writer, "::set-output name=%s::%s\n", k, v)
Expand Down
22 changes: 16 additions & 6 deletions actions/adoptium-dependency/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,25 @@ func main() {
versions[strings.ReplaceAll(r.VersionData.Semver, "+", "-")] = r.Binaries[0].Package.Link
}

for k, _ := range versions {
fmt.Println(k)
latestVersion, err := versions.GetLatestVersion(inputs)
if err != nil {
panic(fmt.Errorf("unable to get latest version\n%w", err))
}

if o, err := versions.GetLatest(inputs); err != nil {
panic(err)
} else {
o.Write(os.Stdout)
outputs, err := actions.NewOutputs(versions[latestVersion.Original()], latestVersion, nil)
if err != nil {
panic(fmt.Errorf("unable to create outputs\n%w", err))
}

if latestVersion.Major() == 8 {
// Java 8 uses `1.8.0` and `updateXX` in the CPE, instead of 8.0.x
//
// This adjusts the update job to set the CPE in this way instead
// of using the standard version format
outputs["cpe"] = fmt.Sprintf("update%d", latestVersion.Patch())
}

outputs.Write(os.Stdout)
}

type Asset struct {
Expand Down
22 changes: 18 additions & 4 deletions actions/alibaba-dragonwell-dependency/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,25 @@ func main() {
h := candidates[candidateVersions[len(candidateVersions)-1]]
versions := actions.Versions{GetVersion(h.Assets): h.URI}

if o, err := versions.GetLatest(inputs); err != nil {
panic(err)
} else {
o.Write(os.Stdout)
latestVersion, err := versions.GetLatestVersion(inputs)
if err != nil {
panic(fmt.Errorf("unable to get latest version\n%w", err))
}

outputs, err := actions.NewOutputs(versions[latestVersion.Original()], latestVersion, nil)
if err != nil {
panic(fmt.Errorf("unable to create outputs\n%w", err))
}

if latestVersion.Major() == 8 {
// Java 8 uses `1.8.0` and `updateXX` in the CPE, instead of 8.0.x
//
// This adjusts the update job to set the CPE in this way instead
// of using the standard version format
outputs["cpe"] = fmt.Sprintf("update%d", latestVersion.Patch())
}

outputs.Write(os.Stdout)
}

func GetVersion(assets []*github.ReleaseAsset) string {
Expand Down
22 changes: 18 additions & 4 deletions actions/amazon-corretto-dependency/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,23 @@ func main() {
opt.Page = rsp.NextPage
}

if o, err := versions.GetLatest(inputs); err != nil {
panic(err)
} else {
o.Write(os.Stdout)
latestVersion, err := versions.GetLatestVersion(inputs)
if err != nil {
panic(fmt.Errorf("unable to get latest version\n%w", err))
}

outputs, err := actions.NewOutputs(versions[latestVersion.Original()], latestVersion, nil)
if err != nil {
panic(fmt.Errorf("unable to create outputs\n%w", err))
}

if latestVersion.Major() == 8 {
// Java 8 uses `1.8.0` and `updateXX` in the CPE, instead of 8.0.x
//
// This adjusts the update job to set the CPE in this way instead
// of using the standard version format
outputs["cpe"] = fmt.Sprintf("update%d", latestVersion.Patch())
}

outputs.Write(os.Stdout)
}
22 changes: 18 additions & 4 deletions actions/azul-zulu-dependency/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,25 @@ func main() {
fmt.Sprintf("%d.%d.%d", raw.JDKVersion[0], raw.JDKVersion[1], raw.JDKVersion[2]): raw.URL,
}

if o, err := versions.GetLatest(inputs); err != nil {
panic(err)
} else {
o.Write(os.Stdout)
latestVersion, err := versions.GetLatestVersion(inputs)
if err != nil {
panic(fmt.Errorf("unable to get latest version\n%w", err))
}

outputs, err := actions.NewOutputs(versions[latestVersion.Original()], latestVersion, nil)
if err != nil {
panic(fmt.Errorf("unable to create outputs\n%w", err))
}

if latestVersion.Major() == 8 {
// Java 8 uses `1.8.0` and `updateXX` in the CPE, instead of 8.0.x
//
// This adjusts the update job to set the CPE in this way instead
// of using the standard version format
outputs["cpe"] = fmt.Sprintf("update%d", latestVersion.Patch())
}

outputs.Write(os.Stdout)
}

type Bundle struct {
Expand Down
22 changes: 18 additions & 4 deletions actions/bellsoft-liberica-dependency/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,25 @@ func main() {
versions[key] = r.DownloadURL
}

if o, err := versions.GetLatest(inputs); err != nil {
panic(err)
} else {
o.Write(os.Stdout)
latestVersion, err := versions.GetLatestVersion(inputs)
if err != nil {
panic(fmt.Errorf("unable to get latest version\n%w", err))
}

outputs, err := actions.NewOutputs(versions[latestVersion.Original()], latestVersion, nil)
if err != nil {
panic(fmt.Errorf("unable to create outputs\n%w", err))
}

if latestVersion.Major() == 8 {
// Java 8 uses `1.8.0` and `updateXX` in the CPE, instead of 8.0.x
//
// This adjusts the update job to set the CPE in this way instead
// of using the standard version format
outputs["cpe"] = fmt.Sprintf("update%d", latestVersion.Patch())
}

outputs.Write(os.Stdout)
}

type Release struct {
Expand Down
22 changes: 18 additions & 4 deletions actions/foojay-dependency/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,25 @@ func main() {

versions := LoadPackages(d, t, v)

if o, err := versions.GetLatest(inputs); err != nil {
panic(err)
} else {
o.Write(os.Stdout)
latestVersion, err := versions.GetLatestVersion(inputs)
if err != nil {
panic(fmt.Errorf("unable to get latest version\n%w", err))
}

outputs, err := actions.NewOutputs(versions[latestVersion.Original()], latestVersion, nil)
if err != nil {
panic(fmt.Errorf("unable to create outputs\n%w", err))
}

if latestVersion.Major() == 8 {
// Java 8 uses `1.8.0` and `updateXX` in the CPE, instead of 8.0.x
//
// This adjusts the update job to set the CPE in this way instead
// of using the standard version format
outputs["cpe"] = fmt.Sprintf("update%d", latestVersion.Patch())
}

outputs.Write(os.Stdout)
}

func LoadPackages(d string, t string, v int) actions.Versions {
Expand Down
22 changes: 18 additions & 4 deletions actions/graalvm-dependency/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,25 @@ func main() {
h := candidates[candidateVersions[len(candidateVersions)-1]]
versions := actions.Versions{GetVersion(h.Assets, v): h.URI}

if o, err := versions.GetLatest(inputs); err != nil {
panic(err)
} else {
o.Write(os.Stdout)
latestVersion, err := versions.GetLatestVersion(inputs)
if err != nil {
panic(fmt.Errorf("unable to get latest version\n%w", err))
}

outputs, err := actions.NewOutputs(versions[latestVersion.Original()], latestVersion, nil)
if err != nil {
panic(fmt.Errorf("unable to create outputs\n%w", err))
}

if latestVersion.Major() == 8 {
// Java 8 uses `1.8.0` and `updateXX` in the CPE, instead of 8.0.x
//
// This adjusts the update job to set the CPE in this way instead
// of using the standard version format
outputs["cpe"] = fmt.Sprintf("update%d", latestVersion.Patch())
}

outputs.Write(os.Stdout)
}

func GetVersion(assets []*github.ReleaseAsset, version string) string {
Expand Down
22 changes: 18 additions & 4 deletions actions/ibm-semeru-dependency/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,25 @@ func main() {
opt.Page = rsp.NextPage
}

if o, err := versions.GetLatest(inputs); err != nil {
panic(err)
} else {
o.Write(os.Stdout)
latestVersion, err := versions.GetLatestVersion(inputs)
if err != nil {
panic(fmt.Errorf("unable to get latest version\n%w", err))
}

outputs, err := actions.NewOutputs(versions[latestVersion.Original()], latestVersion, nil)
if err != nil {
panic(fmt.Errorf("unable to create outputs\n%w", err))
}

if latestVersion.Major() == 8 {
// Java 8 uses `1.8.0` and `updateXX` in the CPE, instead of 8.0.x
//
// This adjusts the update job to set the CPE in this way instead
// of using the standard version format
outputs["cpe"] = fmt.Sprintf("update%d", latestVersion.Patch())
}

outputs.Write(os.Stdout)
}

func getReleaseJSON(jsonURI string) ReleaseJSON {
Expand Down
17 changes: 7 additions & 10 deletions actions/versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (

type Versions map[string]string

func (v Versions) GetLatest(inputs Inputs, mods ...RequestModifierFunc) (Outputs, error) {
func (v Versions) GetLatestVersion(inputs Inputs) (*semver.Version, error) {
if len(v) == 0 {
return nil, fmt.Errorf("no candidate version")
}
Expand Down Expand Up @@ -57,19 +57,16 @@ func (v Versions) GetLatest(inputs Inputs, mods ...RequestModifierFunc) (Outputs
return sv[i].LessThan(sv[j])
})

l := sv[len(sv)-1]
uri := v[l.Original()]
return sv[len(sv)-1], nil
}

sha256, err := SHA256FromURI(uri, mods...)
func (v Versions) GetLatest(inputs Inputs, mods ...RequestModifierFunc) (Outputs, error) {
latestVersion, err := v.GetLatestVersion(inputs)
if err != nil {
return nil, fmt.Errorf("unable to calculate sha256\n%w", err)
return nil, err
}

return Outputs{
"sha256": sha256,
"uri": uri,
"version": fmt.Sprintf("%d.%d.%d", l.Major(), l.Minor(), l.Patch()),
}, nil
return NewOutputs(v[latestVersion.Original()], latestVersion, nil, mods...)
}

var ExtendedVersionPattern = regexp.MustCompile(`^v?([\d]+)\.?([\d]+)?\.?([\d]+)?[-+.]?(.*)$`)
Expand Down
4 changes: 4 additions & 0 deletions octo/buildpack_dependencies.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ func ContributeBuildpackDependencies(descriptor Descriptor) ([]Contribution, err
"URI": "${{ steps.dependency.outputs.uri }}",
"VERSION": "${{ steps.dependency.outputs.version }}",
"VERSION_PATTERN": d.VersionPattern,
"CPE": "${{ steps.dependency.outputs.cpe }}",
"CPE_PATTERN": d.CPEPattern,
"PURL": "${{ steps.dependency.outputs.purl }}",
"PURL_PATTERN": d.PURLPattern,
},
}, {
Uses: "peter-evans/create-pull-request@v3",
Expand Down
2 changes: 2 additions & 0 deletions octo/descriptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ type Dependency struct {
Name string
Id string
VersionPattern string `yaml:"version_pattern"`
PURLPattern string `yaml:"purl_pattern"`
CPEPattern string `yaml:"cpe_pattern"`
Uses string
With map[string]interface{}
}
Expand Down
2 changes: 1 addition & 1 deletion octo/statik/statik.go

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions octo/update-buildpack-dependency.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ update-buildpack-dependency \
--id "${ID}" \
--version-pattern "${VERSION_PATTERN}" \
--version "${VERSION}" \
--cpe-pattern "${CPE_PATTERN:-}" \
--cpe "${CPE:-}" \
--purl-pattern "${PURL_PATTERN:-}" \
--purl "${PURL:-}" \
--uri "${URI}" \
--sha256 "${SHA256}"

Expand Down

0 comments on commit 016cfbd

Please sign in to comment.