From 3af6c93a8edd18c59404620546a4678cfa278708 Mon Sep 17 00:00:00 2001 From: Sophie Wigmore Date: Mon, 20 Sep 2021 17:39:37 -0400 Subject: [PATCH] add SDK compatibility update action --- actions/compatibility/Dockerfile | 10 + actions/compatibility/README.md | 18 + actions/compatibility/action.yml | 26 ++ actions/compatibility/entrypoint/go.mod | 13 + actions/compatibility/entrypoint/go.sum | 134 +++++++ actions/compatibility/entrypoint/main.go | 312 +++++++++++++++ actions/compatibility/entrypoint/main_test.go | 365 ++++++++++++++++++ .../entrypoint/testdata/data.json | 12 + .../testdata/deprecated-releases.json | 12 + .../entrypoint/testdata/releases.json | 31 ++ 10 files changed, 933 insertions(+) create mode 100644 actions/compatibility/Dockerfile create mode 100644 actions/compatibility/README.md create mode 100644 actions/compatibility/action.yml create mode 100644 actions/compatibility/entrypoint/go.mod create mode 100644 actions/compatibility/entrypoint/go.sum create mode 100644 actions/compatibility/entrypoint/main.go create mode 100644 actions/compatibility/entrypoint/main_test.go create mode 100644 actions/compatibility/entrypoint/testdata/data.json create mode 100644 actions/compatibility/entrypoint/testdata/deprecated-releases.json create mode 100644 actions/compatibility/entrypoint/testdata/releases.json diff --git a/actions/compatibility/Dockerfile b/actions/compatibility/Dockerfile new file mode 100644 index 00000000..c544149c --- /dev/null +++ b/actions/compatibility/Dockerfile @@ -0,0 +1,10 @@ +FROM golang:alpine + +RUN apk add \ + bash \ + && rm -rf /var/cache/apk/* + +COPY entrypoint /tmp/entrypoint +RUN cd /tmp/entrypoint && go build -o /entrypoint . + +ENTRYPOINT ["/entrypoint"] diff --git a/actions/compatibility/README.md b/actions/compatibility/README.md new file mode 100644 index 00000000..d19d9130 --- /dev/null +++ b/actions/compatibility/README.md @@ -0,0 +1,18 @@ +## .NET Core SDK Compatibility Table Update Action + +This action updates the .NET Core SDK buildpack.toml file's runtime compatibility table. + +The `entrypoint/main.go` and tests are mostly copied from a previous iteration of this automation that was in the [update-dotnet-sdks-and-compat-table Concourse task](https://github.com/cloudfoundry/buildpacks-ci/tree/master/tasks/cnb/update-dotnet-sdks-and-compat-table). It has been converted into a Github Action. + +To run the code locally: + +1. `cd github-config/actions/compatibility/entrypoint` +2. Run: +``` +go run main.go --buildpack-toml --sdk-version --output-dir +``` +And you may pass an optional `--releases-json-path" flag with a path to a local .NET Core releases.json file that specifies the SDK to runtime compatibilities. If this flag is not passed, the default .NET Core path will be used for the given SDK version line. + +3. Check out the new buildpack.toml + +In keeping with the logic of the old code, the passed in SDK version must be one of the two newest SDK versions available for the given version line. diff --git a/actions/compatibility/action.yml b/actions/compatibility/action.yml new file mode 100644 index 00000000..d3a6c940 --- /dev/null +++ b/actions/compatibility/action.yml @@ -0,0 +1,26 @@ +name: 'Update .NET Core SDK buildpack.toml version compatibility table' + +description: | + This action updates the buildpack.toml runtime/SDK compatibility table. + +inputs: + buildpack_file: + description: 'Path to the buildpack.toml file' + required: true + sdk_version: + description: '.NET Core SDK version' + required: true + output_dir: + description: 'Path to put created artifact' + required: true + +runs: + using: 'docker' + image: 'Dockerfile' + args: + - "--buildpack-toml" + - ${{ inputs.buildpack_file }} + - "--sdk-version" + - ${{ inputs.sdk_version }} + - "--output-dir" + - ${{ inputs.output_dir }} diff --git a/actions/compatibility/entrypoint/go.mod b/actions/compatibility/entrypoint/go.mod new file mode 100644 index 00000000..f283a438 --- /dev/null +++ b/actions/compatibility/entrypoint/go.mod @@ -0,0 +1,13 @@ +module github.com/paketo-buildpacks/github-config/actions/compatibility/entrypoint + +go 1.16 + +require ( + github.com/BurntSushi/toml v0.4.1 + github.com/blang/semver v3.5.1+incompatible + github.com/mitchellh/mapstructure v1.4.1 + github.com/onsi/gomega v1.16.0 + github.com/paketo-buildpacks/packit v1.0.1 + github.com/pkg/errors v0.9.1 + github.com/sclevine/spec v1.4.0 +) diff --git a/actions/compatibility/entrypoint/go.sum b/actions/compatibility/entrypoint/go.sum new file mode 100644 index 00000000..81b20fcd --- /dev/null +++ b/actions/compatibility/entrypoint/go.sum @@ -0,0 +1,134 @@ +github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw= +github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/cheggaaa/pb/v3 v3.0.8/go.mod h1:UICbiLec/XO6Hw6k+BHEtHeQFzzBH4i2/qk/ow1EJTA= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= +github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gabriel-vasile/mimetype v1.3.1/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= +github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/paketo-buildpacks/packit v1.0.1 h1:FHHCZq7WcjXrbA23huRBSOSsNwZvhahc7Rv99i9CWGs= +github.com/paketo-buildpacks/packit v1.0.1/go.mod h1:b4ZPN9PuBGFTfQMfpVXGIXiMiFiYF2slD2OEyfWflC8= +github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8= +github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= +github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/actions/compatibility/entrypoint/main.go b/actions/compatibility/entrypoint/main.go new file mode 100644 index 00000000..537d9eb7 --- /dev/null +++ b/actions/compatibility/entrypoint/main.go @@ -0,0 +1,312 @@ +package main + +import ( + "encoding/json" + "flag" + "fmt" + "io/ioutil" + "net/http" + "os" + "path/filepath" + "sort" + "strings" + + "github.com/paketo-buildpacks/packit/cargo" + + "github.com/blang/semver" + "github.com/mitchellh/mapstructure" + _ "github.com/pkg/errors" +) + +var ( + flags struct { + buildpackTOML string + runtimeVersion string + outputDir string + sdkVersion string + releasesJSONPath string + } + channel Channel +) + +type RuntimeToSDK struct { + RuntimeVersion string `toml:"runtime-version" json:"runtime-version"` + SDKs []string `toml:"sdks" json:"sdks"` +} + +type Channel struct { + Releases []Release `json:"releases"` + LatestRuntime string `json:"latest-runtime"` + ChannelVersion string `json:"channel-version"` +} + +type Release struct { + Runtime struct { + Version string `json:"version"` + } `json:"runtime,omitempty"` + Sdk struct { + Version string `json:"version"` + } `json:"sdk,omitempty"` +} + +func main() { + var err error + + flag.StringVar(&flags.buildpackTOML, "buildpack-toml", "", "path to input buildpack.toml file") + flag.StringVar(&flags.outputDir, "output-dir", "", "directory to write buildpack.toml to") + flag.StringVar(&flags.sdkVersion, "sdk-version", "", "version of sdk") + flag.StringVar(&flags.releasesJSONPath, "releases-json-path", "", "path to dotnet releases.json") + flag.Parse() + + channel, err = getReleaseChannel() + if err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } + + flags.runtimeVersion, err = getRuntimeVersion() + if err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } + + err = updateCompatibilityTable() + if err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } +} + +func updateCompatibilityTable() error { + buildpackTOML := cargo.Config{} + + file, err := os.Open(flags.buildpackTOML) + if err != nil { + return fmt.Errorf("failed to open buildpack.toml file: %w", err) + } + + defer file.Close() + if err = cargo.DecodeConfig(file, &buildpackTOML); err != nil { + return fmt.Errorf("failed to load buildpack toml: %w", err) + } + supported, err := checkIfSupportedPatchVersion() + if err != nil { + return err + } + + versionToRemove := flags.sdkVersion + if supported { + versionToRemove, buildpackTOML, err = addSDKToRuntime(buildpackTOML, flags.sdkVersion, flags.runtimeVersion) + if err != nil { + return fmt.Errorf("failed to add sdk to runtime mapping: %w", err) + } + } else { + fmt.Println("this runtime patch version is not supported. only the two latest versions are supported") + } + + buildpackTOML, err = removeUnusedSDK(buildpackTOML, versionToRemove) + if err != nil { + return fmt.Errorf("failed to removed unused sdk: %w", err) + } + + buildpackTOMLFile, err := os.Create(filepath.Join(flags.outputDir, "buildpack.toml")) + if err != nil { + return fmt.Errorf("failed to open buildpack.toml at: %s", flags.outputDir) + } + defer buildpackTOMLFile.Close() + + if err := cargo.EncodeConfig(buildpackTOMLFile, buildpackTOML); err != nil { + return fmt.Errorf("failed to update buildpack toml: %w", err) + } + + return nil +} + +func checkIfSupportedPatchVersion() (bool, error) { + latestRuntime, secondLatestRuntime, err := getLatestTwoSupportedRuntimeVersions() + if err != nil { + return false, fmt.Errorf("failed to get two supported versions of runtime: %w", err) + } + + return flags.runtimeVersion == latestRuntime || flags.runtimeVersion == secondLatestRuntime, nil +} + +func getLatestTwoSupportedRuntimeVersions() (string, string, error) { + latestRuntime := channel.LatestRuntime + secondLatestRuntime := "" + for _, release := range channel.Releases { + if release.Runtime.Version != latestRuntime { + secondLatestRuntime = release.Runtime.Version + break + } + } + return latestRuntime, secondLatestRuntime, nil +} + +func getRuntimeVersion() (string, error) { + for _, release := range channel.Releases { + if release.Sdk.Version == flags.sdkVersion { + return release.Runtime.Version, nil + } + } + return "", fmt.Errorf("failed to get SDK %s compatible runtime from %s", flags.sdkVersion, flags.releasesJSONPath) +} + +func getReleaseChannel() (Channel, error) { + var releasesJSON []byte + var err error + + // if the explicit release JSON file isn't passed in, look up the version-specific JSON file from the official release.json URI + if flags.releasesJSONPath == "" { + semverSdkVersion, err := semver.New(flags.sdkVersion) + if err != nil { + return Channel{}, fmt.Errorf("failed to parse SDK version into semantic version: %w", err) + } + + url := fmt.Sprintf("https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/%d.%d/releases.json", semverSdkVersion.Major, semverSdkVersion.Minor) + fmt.Printf("getting releases from %s", url) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return Channel{}, fmt.Errorf("failed to create request to %s: %w", url, err) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return Channel{}, fmt.Errorf("failed to reach out to %s: %w", url, err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return Channel{}, err + } + + releasesJSON, err = ioutil.ReadAll(resp.Body) + if err != nil { + return Channel{}, fmt.Errorf("failed to read releases.json: %w", err) + } + } else { + releasesJSON, err = ioutil.ReadFile(flags.releasesJSONPath) + if err != nil { + return Channel{}, fmt.Errorf("failed to read releases.json: %w", err) + } + } + + if err := json.Unmarshal(releasesJSON, &channel); err != nil { + return Channel{}, fmt.Errorf("failed to unmarshal releases.json: %w", err) + } + return channel, nil +} + +func removeUnsupportedRuntime(inputs []RuntimeToSDK) (string, []RuntimeToSDK, error) { + + latestRuntime, secondLatestRuntime, err := getLatestTwoSupportedRuntimeVersions() + if err != nil { + return "", nil, fmt.Errorf("failed to get two supported versions of runtime: %w", err) + } + + channelVersion := channel.ChannelVersion + var inputWithoutUnsupportedRuntime []RuntimeToSDK + var sdkVersionToRemove string + + for _, runtimeToSDK := range inputs { + if isSupportedRuntime(runtimeToSDK, channelVersion, latestRuntime, secondLatestRuntime) { + inputWithoutUnsupportedRuntime = append(inputWithoutUnsupportedRuntime, runtimeToSDK) + } else { + sdkVersionToRemove = runtimeToSDK.SDKs[0] + } + + } + + return sdkVersionToRemove, inputWithoutUnsupportedRuntime, nil +} + +func isSupportedRuntime(runtimeToSDK RuntimeToSDK, channelVersion string, latestRuntime string, secondLatestRuntime string) bool { + return !(strings.Contains(runtimeToSDK.RuntimeVersion, channelVersion) && + runtimeToSDK.RuntimeVersion != latestRuntime && + runtimeToSDK.RuntimeVersion != secondLatestRuntime) +} + +func addSDKToRuntime(buildpackTOML cargo.Config, sdkVersion, runtimeVersion string) (string, cargo.Config, error) { + var versionToRemove string + var inputs []RuntimeToSDK + + if buildpackTOML.Metadata.Unstructured != nil { + err := json.Unmarshal([]byte(buildpackTOML.Metadata.Unstructured["runtime-to-sdks"].(json.RawMessage)), &inputs) + if err != nil { + return "cannot decode runtime to sdk keys from buildpacks TOML", buildpackTOML, err + } + } + + versionToRemove, inputs, err := removeUnsupportedRuntime(inputs) + if err != nil { + return "cannot remove unsupported runtime from buildpacks TOML", buildpackTOML, err + } + + runtimeExists := false + for _, runtimeToSDK := range inputs { + if runtimeToSDK.RuntimeVersion == runtimeVersion { + var updatedSDK string + updatedSDK, versionToRemove, err = checkSDK(sdkVersion, runtimeToSDK.SDKs[0]) + if err != nil { + return "", buildpackTOML, err + } + runtimeToSDK.SDKs[0] = updatedSDK + runtimeExists = true + break + } + } + + if !runtimeExists { + inputs = append(inputs, RuntimeToSDK{ + RuntimeVersion: runtimeVersion, + SDKs: []string{sdkVersion}, + }) + } + sort.Slice(inputs, func(i, j int) bool { + firstRuntime := semver.MustParse(inputs[i].RuntimeVersion) + secondRuntime := semver.MustParse(inputs[j].RuntimeVersion) + return firstRuntime.LT(secondRuntime) + }) + + buildpackTOML.Metadata.Unstructured = make(map[string]interface{}) + buildpackTOML.Metadata.Unstructured["runtime-to-sdks"] = inputs + + return versionToRemove, buildpackTOML, nil +} + +func checkSDK(callingSDK, existingSDK string) (string, string, error) { + var versionToRemove string + updatedSDK := existingSDK + + currentSdkVersion, err := semver.New(existingSDK) + if err != nil { + return "", "", err + } + newSdkVersion, err := semver.New(callingSDK) + if err != nil { + return "", "", err + } + + if newSdkVersion.GT(*currentSdkVersion) { + versionToRemove = existingSDK + updatedSDK = callingSDK + } else if newSdkVersion.LT(*currentSdkVersion) { + versionToRemove = callingSDK + } + return updatedSDK, versionToRemove, nil +} + +func removeUnusedSDK(buildpackTOML cargo.Config, sdkVersion string) (cargo.Config, error) { + var dependencies []cargo.ConfigMetadataDependency + err := mapstructure.Decode(buildpackTOML.Metadata.Dependencies, &dependencies) + if err != nil { + return buildpackTOML, err + } + for i, dependency := range dependencies { + if dependency.Version == sdkVersion { + dependencies = append(dependencies[:i], dependencies[i+1:]...) + break + } + } + buildpackTOML.Metadata.Dependencies = dependencies + return buildpackTOML, nil +} diff --git a/actions/compatibility/entrypoint/main_test.go b/actions/compatibility/entrypoint/main_test.go new file mode 100644 index 00000000..e39767d4 --- /dev/null +++ b/actions/compatibility/entrypoint/main_test.go @@ -0,0 +1,365 @@ +package main_test + +import ( + "encoding/json" + "os" + "os/exec" + "path/filepath" + "testing" + + "github.com/mitchellh/mapstructure" + . "github.com/onsi/gomega" + . "github.com/paketo-buildpacks/github-config/actions/compatibility/entrypoint" + "github.com/paketo-buildpacks/packit/cargo" + "github.com/sclevine/spec" +) + +func TestSDKCompatibilityTableUpdate(t *testing.T) { + spec.Run(t, "SDKCompatibilityTableUpdate", func(t *testing.T, context spec.G, it spec.S) { + var ( + Expect = NewWithT(t).Expect + err error + outputDir string + releasesJSON string + ) + + it.Before(func() { + RegisterTestingT(t) + outputDir, err = os.MkdirTemp("", "output") + Expect(err).NotTo(HaveOccurred()) + releasesJSON = filepath.Join("testdata", "releases.json") + }) + + it.After(func() { + Expect(os.RemoveAll(outputDir)).To(Succeed()) + }) + + context("with empty buildpack.toml", func() { + it("add version of sdk dependency", func() { + buildpackTOML := cargo.Config{ + API: "0.2", + Buildpack: cargo.ConfigBuildpack{}, + Metadata: cargo.ConfigMetadata{}, + } + runTask(buildpackTOML, releasesJSON, "2.1.803", outputDir) + + outputBuildpackToml := decodeBuildpackTOML(outputDir) + + var compatibilityTable []RuntimeToSDK + err = json.Unmarshal([]byte(outputBuildpackToml.Metadata.Unstructured["runtime-to-sdks"].(json.RawMessage)), &compatibilityTable) + Expect(err).NotTo(HaveOccurred()) + Expect(compatibilityTable).To(Equal([]RuntimeToSDK{ + { + RuntimeVersion: "2.1.15", + SDKs: []string{"2.1.803"}, + }, + })) + + }) + }) + + context("with version that doesn't exist in buildpack.toml", func() { + it("add version of sdk dependency and sorts versions", func() { + buildpackTOML := cargo.Config{ + Metadata: cargo.ConfigMetadata{ + Unstructured: map[string]interface{}{ + "runtime-to-sdks": []RuntimeToSDK{ + {RuntimeVersion: "2.1.14", SDKs: []string{"2.1.607"}}, + }, + }, + }, + } + + runTask(buildpackTOML, releasesJSON, "2.1.803", outputDir) + + outputBuildpackToml := decodeBuildpackTOML(outputDir) + + var compatibilityTable []RuntimeToSDK + err = json.Unmarshal([]byte(outputBuildpackToml.Metadata.Unstructured["runtime-to-sdks"].(json.RawMessage)), &compatibilityTable) + Expect(err).NotTo(HaveOccurred()) + + Expect(compatibilityTable).To(Equal([]RuntimeToSDK{ + { + RuntimeVersion: "2.1.14", + SDKs: []string{"2.1.607"}, + }, + { + RuntimeVersion: "2.1.15", + SDKs: []string{"2.1.803"}, + }, + })) + }) + + context("the runtime version is not one of the two latest supported versions", func() { + it("does not add to the compatibility table", func() { + buildpackTOML := cargo.Config{ + Metadata: cargo.ConfigMetadata{ + Dependencies: []cargo.ConfigMetadataDependency{ + {ID: "dotnet-sdk", Version: "2.1.801"}, + }, + }, + } + + taskOutput := runTask(buildpackTOML, releasesJSON, "2.1.801", outputDir) + + Expect(taskOutput).To(ContainSubstring("this runtime patch version is not supported. only the two latest versions are supported")) + + outputBuildpackToml := decodeBuildpackTOML(outputDir) + + var dependencies []cargo.ConfigMetadataDependency + + err = mapstructure.Decode(outputBuildpackToml.Metadata.Unstructured["dependencies"], &dependencies) + Expect(err).NotTo(HaveOccurred()) + Expect(dependencies).To(BeEmpty()) + }) + }) + }) + + context("runtime version is present in buildpack.toml", func() { + it("include only one latest version of sdk dependency", func() { + buildpackTOML := cargo.Config{ + Metadata: cargo.ConfigMetadata{ + Dependencies: []cargo.ConfigMetadataDependency{ + {ID: "dotnet-sdk", Version: "1.1.801"}, + {ID: "dotnet-sdk", Version: "2.1.606"}, + {ID: "dotnet-sdk", Version: "2.1.607"}, + }, + Unstructured: map[string]interface{}{ + "runtime-to-sdks": []RuntimeToSDK{ + {RuntimeVersion: "1.1.13", SDKs: []string{"1.1.801"}}, + {RuntimeVersion: "2.1.14", SDKs: []string{"2.1.606"}}, + }, + }, + }, + } + + runTask(buildpackTOML, releasesJSON, "2.1.607", outputDir) + + outputBuildpackToml := decodeBuildpackTOML(outputDir) + + var compatibilityTable []RuntimeToSDK + err = json.Unmarshal([]byte(outputBuildpackToml.Metadata.Unstructured["runtime-to-sdks"].(json.RawMessage)), &compatibilityTable) + Expect(err).NotTo(HaveOccurred()) + Expect(compatibilityTable).To(Equal( + []RuntimeToSDK{ + { + RuntimeVersion: "1.1.13", + SDKs: []string{"1.1.801"}, + }, + { + RuntimeVersion: "2.1.14", + SDKs: []string{"2.1.607"}, + }, + })) + + var dependencies []cargo.ConfigMetadataDependency + err = mapstructure.Decode(outputBuildpackToml.Metadata.Dependencies, &dependencies) + Expect(err).NotTo(HaveOccurred()) + + Expect(dependencies).To(Equal([]cargo.ConfigMetadataDependency{ + {ID: "dotnet-sdk", Version: "1.1.801"}, + {ID: "dotnet-sdk", Version: "2.1.607"}, + })) + }) + }) + + context("runtime version is not present in buildpack.toml", func() { + it("include only two latest versions of runtime dependency", func() { + buildpackTOML := cargo.Config{ + Metadata: cargo.ConfigMetadata{ + Dependencies: []cargo.ConfigMetadataDependency{ + {ID: "dotnet-sdk", Version: "2.1.605"}, + {ID: "dotnet-sdk", Version: "2.1.606"}, + {ID: "dotnet-sdk", Version: "2.1.801"}, + }, + Unstructured: map[string]interface{}{ + "runtime-to-sdks": []RuntimeToSDK{ + {RuntimeVersion: "2.1.13", SDKs: []string{"2.1.605"}}, + {RuntimeVersion: "2.1.14", SDKs: []string{"2.1.606"}}, + }, + }, + }, + } + + runTask(buildpackTOML, releasesJSON, "2.1.803", outputDir) + + outputBuildpackToml := decodeBuildpackTOML(outputDir) + + var compatibilityTable []RuntimeToSDK + err = json.Unmarshal([]byte(outputBuildpackToml.Metadata.Unstructured["runtime-to-sdks"].(json.RawMessage)), &compatibilityTable) + Expect(err).NotTo(HaveOccurred()) + + Expect(compatibilityTable).To(Equal( + []RuntimeToSDK{ + { + RuntimeVersion: "2.1.14", + SDKs: []string{"2.1.606"}, + }, + { + RuntimeVersion: "2.1.15", + SDKs: []string{"2.1.803"}, + }, + })) + + var dependencies []cargo.ConfigMetadataDependency + err = mapstructure.Decode(outputBuildpackToml.Metadata.Dependencies, &dependencies) + Expect(err).NotTo(HaveOccurred()) + Expect(dependencies).To(Equal([]cargo.ConfigMetadataDependency{ + {ID: "dotnet-sdk", Version: "2.1.606"}, + {ID: "dotnet-sdk", Version: "2.1.801"}, + })) + }) + }) + + context("dotnet runtime already has latest sdk depedency", func() { + context("the sdk is the latest version", func() { + it("does not update or remove from buildpack.toml", func() { + buildpackTOML := cargo.Config{ + Metadata: cargo.ConfigMetadata{ + Dependencies: []cargo.ConfigMetadataDependency{ + {ID: "dotnet-sdk", Version: "2.1.607"}, + }, + Unstructured: map[string]interface{}{ + "runtime-to-sdks": []RuntimeToSDK{ + {RuntimeVersion: "2.1.14", SDKs: []string{"2.1.607"}}, + }, + }, + }, + } + + runTask(buildpackTOML, releasesJSON, "2.1.607", outputDir) + + outputBuildpackToml := decodeBuildpackTOML(outputDir) + + var compatibilityTable []RuntimeToSDK + err = json.Unmarshal([]byte(outputBuildpackToml.Metadata.Unstructured["runtime-to-sdks"].(json.RawMessage)), &compatibilityTable) + Expect(err).NotTo(HaveOccurred()) + Expect(compatibilityTable).To(Equal( + []RuntimeToSDK{ + { + RuntimeVersion: "2.1.14", + SDKs: []string{"2.1.607"}, + }, + })) + + var dependencies []cargo.ConfigMetadataDependency + err = mapstructure.Decode(outputBuildpackToml.Metadata.Dependencies, &dependencies) + + Expect(err).NotTo(HaveOccurred()) + Expect(dependencies).To(Equal([]cargo.ConfigMetadataDependency{ + {ID: "dotnet-sdk", Version: "2.1.607"}, + })) + }) + }) + }) + + it("should keep the integrity of the rest of the toml", func() { + buildpackTOML := cargo.Config{ + API: "0.2", + Metadata: cargo.ConfigMetadata{ + Dependencies: []cargo.ConfigMetadataDependency{ + {ID: "dotnet-sdk", Version: "2.1.607"}, + {ID: "dotnet-sdk", Version: "2.1.802"}, + {ID: "dotnet-sdk", Version: "2.1.803"}, + }, + Unstructured: map[string]interface{}{ + "runtime-to-sdks": []RuntimeToSDK{ + {RuntimeVersion: "2.1.14", SDKs: []string{"2.1.607"}}, + {RuntimeVersion: "2.1.15", SDKs: []string{"2.1.802"}}, + }, + }, + }, + Stacks: []cargo.ConfigStack{ + {ID: "org.cloudfoundry.stacks.cflinuxfs3"}, + {ID: "io.buildpacks.stacks.bionic"}, + }, + } + + runTask(buildpackTOML, releasesJSON, "2.1.803", outputDir) + + outputBuildpackToml := decodeBuildpackTOML(outputDir) + Expect("0.2").To(Equal(outputBuildpackToml.API)) + Expect(len(outputBuildpackToml.Stacks)).To(Equal(2)) + }) + + context("failure cases", func() { + context("the sdk version is not in the releases page", func() { + it("errors out", func() { + buildpackTOML := cargo.Config{ + Metadata: cargo.ConfigMetadata{ + Dependencies: []cargo.ConfigMetadataDependency{ + {ID: "dotnet-sdk", Version: "2.1.606"}, + {ID: "dotnet-sdk", Version: "2.1.607"}, + }, + Unstructured: map[string]interface{}{ + "runtime-to-sdks": []RuntimeToSDK{ + {RuntimeVersion: "2.1.14", SDKs: []string{"2.1.607"}}, + }, + }, + }, + } + + _, err := runTaskError(buildpackTOML, releasesJSON, "2.1.606", outputDir) + Expect(err).To(HaveOccurred()) + }) + }) + + }) + }) +} + +func decodeBuildpackTOML(outputDir string) cargo.Config { + var buildpackTOML cargo.Config + file, err := os.Open(filepath.Join(outputDir, "buildpack.toml")) + Expect(err).NotTo(HaveOccurred()) + err = cargo.DecodeConfig(file, &buildpackTOML) + Expect(err).NotTo(HaveOccurred()) + + defer file.Close() + return buildpackTOML +} + +func runTask(buildpackTOML cargo.Config, releasesJSON, sdkVersion, outputDir string) string { + setupOutputDirectory(outputDir, buildpackTOML) + + taskCmd := exec.Command( + "go", "run", "main.go", + "--buildpack-toml", filepath.Join(outputDir, "buildpack.toml"), + "--releases-json-path", releasesJSON, + "--sdk-version", sdkVersion, + "--output-dir", outputDir, + ) + taskCmd.Env = append(taskCmd.Env, "HOME="+os.Getenv("HOME"), "PATH="+os.Getenv("PATH")) + + taskOutput, err := taskCmd.CombinedOutput() + Expect(err).NotTo(HaveOccurred()) + return string(taskOutput) +} + +func runTaskError(buildpackTOML cargo.Config, releasesJSON, sdkVersion, outputDir string) (string, error) { + setupOutputDirectory(outputDir, buildpackTOML) + + taskCmd := exec.Command( + "go", "run", "main.go", + "--buildpack-toml", filepath.Join(outputDir, "buildpack.toml"), + "--releases-json-path", releasesJSON, + "--sdk-version", sdkVersion, + "--output-dir", outputDir, + ) + taskCmd.Env = append(taskCmd.Env, "HOME="+os.Getenv("HOME"), "PATH="+os.Getenv("PATH")) + + taskOutput, err := taskCmd.CombinedOutput() + return string(taskOutput), err +} + +func setupOutputDirectory(outputDir string, buildpackTOML cargo.Config) { + Expect(os.RemoveAll(outputDir)).To(Succeed()) + Expect(os.Mkdir(outputDir, 0755)).To(Succeed()) + + buildpackTOMLFile, err := os.Create(filepath.Join(outputDir, "buildpack.toml")) + Expect(err).ToNot(HaveOccurred()) + defer buildpackTOMLFile.Close() + + err = cargo.EncodeConfig(buildpackTOMLFile, buildpackTOML) + Expect(err).ToNot(HaveOccurred()) +} diff --git a/actions/compatibility/entrypoint/testdata/data.json b/actions/compatibility/entrypoint/testdata/data.json new file mode 100644 index 00000000..c118c8a0 --- /dev/null +++ b/actions/compatibility/entrypoint/testdata/data.json @@ -0,0 +1,12 @@ +{ + "source": { + "name": "some-dep", + "type": "some-dep", + "version_filter": "2.X.X" + }, + "version": { + "ref": "2.1.0", + "url": "https://example.org/some-dep-2.1.0-source.tgz", + "sha256": "sha256-for-source-2.1.0" + } +} diff --git a/actions/compatibility/entrypoint/testdata/deprecated-releases.json b/actions/compatibility/entrypoint/testdata/deprecated-releases.json new file mode 100644 index 00000000..8cba4712 --- /dev/null +++ b/actions/compatibility/entrypoint/testdata/deprecated-releases.json @@ -0,0 +1,12 @@ +{ + "channel-version": "2.1", + "eol-date": "2000-08-21", + "releases": [ + { + "release-version": "2.1.15", + "runtime": { "version": "2.1.15" }, + "sdk": { "version": "2.1.803" }, + "aspnetcore-runtime": { "version": "2.1.15" } + } + ] +} diff --git a/actions/compatibility/entrypoint/testdata/releases.json b/actions/compatibility/entrypoint/testdata/releases.json new file mode 100644 index 00000000..43bf6843 --- /dev/null +++ b/actions/compatibility/entrypoint/testdata/releases.json @@ -0,0 +1,31 @@ +{ + "channel-version": "2.1", + "eol-date": "2099-08-21", + "latest-runtime": "2.1.15", + "releases": [ + { + "release-version": "2.1.15", + "runtime": { "version": "2.1.15" }, + "sdk": { "version": "2.1.803" }, + "aspnetcore-runtime": { "version": "2.1.15" } + }, + { + "release-version": "2.1.14", + "runtime": { "version": "2.1.14" }, + "sdk": { "version": "2.1.607" }, + "aspnetcore-runtime": { "version": "2.1.14" } + }, + { + "release-version": "2.1.802", + "runtime": { "version": "2.1.13" }, + "sdk": { "version": "2.1.802" }, + "aspnetcore-runtime": { "version": "2.1.13" } + }, + { + "release-version": "2.1.13", + "runtime": { "version": "2.1.13" }, + "sdk": { "version": "2.1.801" }, + "aspnetcore-runtime": { "version": "2.1.13" } + } + ] +}