diff --git a/.github/scripts/release-workflow-package-push.sh b/.github/scripts/release-workflow-package-push.sh deleted file mode 100755 index 1b2fd8087..000000000 --- a/.github/scripts/release-workflow-package-push.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# This script is an integral part of the release workflow: .github/workflows/release.yml -# It requires the following environment variables to function correctly: -# -# REQUESTED_BUILDPACK_ID - The ID of the buildpack to package and push to the container registry. - -while IFS="" read -r -d "" buildpack_toml_path; do - buildpack_id="$(yj -t <"${buildpack_toml_path}" | jq -r .buildpack.id)" - buildpack_version="$(yj -t <"${buildpack_toml_path}" | jq -r .buildpack.version)" - buildpack_docker_repository="$(yj -t <"${buildpack_toml_path}" | jq -r .metadata.release.docker.repository)" - buildpack_path=$(dirname "${buildpack_toml_path}") - buildpack_build_path="${buildpack_path}" - - if [[ $buildpack_id == "${REQUESTED_BUILDPACK_ID}" ]]; then - # Some buildpacks require a build step before packaging. If we detect a build.sh script, we execute it and - # modify the buildpack_build_path variable to point to the directory with the built buildpack instead. - if [[ -f "${buildpack_path}/build.sh" ]]; then - echo "Buildpack has build script, executing..." - "${buildpack_path}/build.sh" - echo "Build finished!" - - buildpack_build_path="${buildpack_path}/target" - fi - - image_name="${buildpack_docker_repository}:${buildpack_version}" - pack package-buildpack --config "${buildpack_build_path}/package.toml" --publish "${image_name}" - - # We might have local changes after building and/or shimming the buildpack. To ensure scripts down the pipeline - # work with a clean state, we reset all local changes here. - git reset --hard - git clean -fdx - - echo "::set-output name=id::${buildpack_id}" - echo "::set-output name=version::${buildpack_version}" - echo "::set-output name=path::${buildpack_path}" - echo "::set-output name=address::${buildpack_docker_repository}@$(crane digest "${image_name}")" - exit 0 - fi -done < <(find . -name buildpack.toml -print0) - -echo "Could not find requested buildpack with id ${REQUESTED_BUILDPACK_ID}!" -exit 1 diff --git a/.github/scripts/release-workflow-prepare-pr.sh b/.github/scripts/release-workflow-prepare-pr.sh deleted file mode 100755 index 59cd9c960..000000000 --- a/.github/scripts/release-workflow-prepare-pr.sh +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -released_buildpack_id="${1:?}" -released_buildpack_version="${2:?}" -released_buildpack_image_address="${3:?}" - -released_buildpack_next_version=$( - echo "${released_buildpack_version}" | awk -F. -v OFS=. '{ $NF=sprintf("%d\n", ($NF+1)); printf $0 }' -) - -function escape_for_sed() { - echo "${1:?}" | sed 's/[]\/\[\.]/\\&/g' -} - -function is_meta_buildpack_with_dependency() { - local -r buildpack_toml_path="${1:?}" - local -r buildpack_id="${2:?}" - - yj -t <"${buildpack_toml_path}" | jq -e "[.order[]?.group[]?.id | select(. == \"${buildpack_id}\")] | length > 0" >/dev/null -} - -function package_toml_contains_image_address_root() { - local -r package_toml_path="${1:?}" - local -r image_address_root="${2:?}" - - yj -t <"${package_toml_path}" | jq -e "[.dependencies[].uri | select(startswith(\"${image_address_root}\"))] | length > 0" >/dev/null -} - -# This is the heading we're looking for when updating CHANGELOG.md files -unreleased_heading=$(escape_for_sed "## [Unreleased]") - -while IFS="" read -r -d "" buildpack_toml_path; do - buildpack_id="$(yj -t <"${buildpack_toml_path}" | jq -r .buildpack.id)" - buildpack_path="$(dirname "${buildpack_toml_path}")" - buildpack_package_toml_path="${buildpack_path}/package.toml" - buildpack_changelog_path="${buildpack_path}/CHANGELOG.md" - - jq_filter="." - - # Update the released buildpack itself - if [[ "${buildpack_id}" == "${released_buildpack_id}" ]]; then - if [[ -f "${buildpack_changelog_path}" ]]; then - new_version_heading=$(escape_for_sed "## [${released_buildpack_version}] $(date +%Y/%m/%d)") - sed -i "s/${unreleased_heading}/${unreleased_heading}\n\n${new_version_heading}/" "${buildpack_changelog_path}" - fi - - jq_filter=".buildpack.version = \"${released_buildpack_next_version}\"" - - # Update meta-buildpacks that have the released buildpack as a dependency - elif is_meta_buildpack_with_dependency "${buildpack_toml_path}" "${released_buildpack_id}"; then - # There are two cases of meta-buildpacks that reference the released buildpack: - # - # 1. The released buildpack is referenced by a local path. In this case, we need to update the reference to - # the next version, not the released version. - # 2. The released buildpack is referenced by a Docker address. In this case, we need to update the reference - # to the released version instead. - target_version_for_meta_buildpack="${released_buildpack_next_version}" - - released_buildpack_image_address_root="${released_buildpack_image_address%@*}" - if package_toml_contains_image_address_root "${buildpack_package_toml_path}" "${released_buildpack_image_address_root}"; then - target_version_for_meta_buildpack="${released_buildpack_version}" - - package_toml_filter=".dependencies[].uri |= if startswith(\"${released_buildpack_image_address_root}\") then \"${released_buildpack_image_address}\" else . end" - updated_package_toml=$(yj -t <"${buildpack_package_toml_path}" | jq "${package_toml_filter}" | yj -jt) - echo "${updated_package_toml}" >"${buildpack_package_toml_path}" - fi - - if [[ -f "${buildpack_changelog_path}" ]]; then - upgrade_entry=$( - escape_for_sed "* Upgraded \`${released_buildpack_id}\` to \`${target_version_for_meta_buildpack}\`" - ) - - sed -i "s/${unreleased_heading}/${unreleased_heading}\n${upgrade_entry}/" "${buildpack_changelog_path}" - fi - - jq_filter=$( - cat <<-EOF - .order |= map(.group |= map( - if .id == "${released_buildpack_id}" then - .version |= "${target_version_for_meta_buildpack}" - else - . - end - )) - EOF - ) - fi - - # Write the filtered buildpack.toml to disk... - updated=$(yj -t <"${buildpack_toml_path}" | jq "${jq_filter}" | yj -jt) - echo "${updated}" >"${buildpack_toml_path}" - -done < <(find . -name buildpack.toml -print0) diff --git a/Rakefile b/Rakefile index 1a46f363c..6220d0b7e 100644 --- a/Rakefile +++ b/Rakefile @@ -9,7 +9,6 @@ require 'hatchet/tasks' ENV["BUILDPACK_LOG_FILE"] ||= "tmp/buildpack.log" require_relative 'lib/rake/deploy_check' -require_relative 'lib/rake/tarballer' S3_BUCKET_REGION = "us-east-1" S3_BUCKET_NAME = "heroku-buildpack-ruby" @@ -68,39 +67,7 @@ end namespace :buildpack do desc "prepares the next version of the buildpack for release" task :prepare do - deploy = DeployCheck.new(github: "heroku/heroku-buildpack-ruby") - unreleased_changelogs = Pathname(__dir__).join("changelogs/unreleased").glob("*.md") - if unreleased_changelogs.empty? - puts "No devcenter changelog entries on disk in changelogs/unreleased" - else - next_changelog_dir = Pathname(__dir__).join("changelogs").join(deploy.next_version.to_s) - - next_changelog_dir.mkpath - - unreleased_changelogs.each do |source| - dest = next_changelog_dir.join(source.basename) - puts "Moving #{source} to #{dest}" - FileUtils.mv(source, dest) - end - end - - changelog_md = Pathname(__dir__).join("CHANGELOG.md") - contents = changelog_md.read - version_string = "## #{deploy.next_version}" - if contents.include?(version_string) - puts "Found an entry in CHANGELOG.md for #{version_string}" - else - new_section = "## Main (unreleased)\n\n#{version_string} (#{Time.now.strftime("%Y/%m/%d")})" - - puts "Writing to CHANGELOG.md:\n\n#{new_section}" - - changelog_md.write(contents.gsub("## Main (unreleased)", new_section)) - end - - version_rb = Pathname(__dir__).join("lib/language_pack/version.rb") - puts "Updating version.rb" - contents = version_rb.read.gsub(/BUILDPACK_VERSION = .*$/, %Q{BUILDPACK_VERSION = "#{deploy.next_version.to_s}"}) - version_rb.write(contents) + puts("Use https://github.com/heroku/heroku-buildpack-ruby/actions/workflows/prepare-release.yml") end desc "releases the next version of the buildpack" @@ -122,11 +89,6 @@ namespace :buildpack do puts "Releasing to heroku: `#{command}`" exec(command) end - desc "stage a tarball of the buildpack, this runs on github actions to deploy CNB" - task :tarball do - tarballer = Tarballer.new(name: "heroku-buildpack-ruby", directory: __dir__) - tarballer.call - end end desc "update plugins" diff --git a/lib/rake/deploy_check.rb b/lib/rake/deploy_check.rb index 63b00f03c..3cfeb6146 100644 --- a/lib/rake/deploy_check.rb +++ b/lib/rake/deploy_check.rb @@ -67,8 +67,8 @@ def check_branch!(name = "main") # Raises an error if the changelog does not have an entry with the designated version def check_changelog! - if !File.read("CHANGELOG.md").include?("## #{next_version}") - raise "Expected CHANGELOG.md to include #{next_version} but it did not" + if !File.read("CHANGELOG.md").include?("## [#{next_version}]") + raise "Expected CHANGELOG.md to include [#{next_version}] but it did not" end end diff --git a/lib/rake/tarballer.rb b/lib/rake/tarballer.rb deleted file mode 100644 index be87a68b3..000000000 --- a/lib/rake/tarballer.rb +++ /dev/null @@ -1,52 +0,0 @@ -require 'fileutils' -require 'pathname' - -$:.unshift File.join(__dir__, "..") # put lib on the path -require "language_pack/installers/heroku_ruby_installer" -require "language_pack/ruby_version" -require "language_pack/version" - -# This class takes a target directory (such as the buildpack) -# and tars it up so it's in a form ready to be run -# -# In addition to TAR logic it also vendors ruby versions so -# they don't need to be pulled at runtime -class Tarballer - STACKS = %W{heroku-20 heroku-22} - - def initialize(name: , directory: , io: STDOUT) - @name = name - @source_directory = Pathname.new(directory) - @version = LanguagePack::Base::BUILDPACK_VERSION - @dest_directory = @source_directory.join("buildpacks") - @dest_directory.mkpath - @io = io - end - - def call(stacks: STACKS) - Dir.mktmpdir do |tmpdir_base| - tmp_dir = Pathname.new(tmpdir_base).join(@name) - run! "cp -r #{@source_directory} #{tmp_dir}" - - Dir.chdir(tmp_dir) do |buildpack_dir| - stacks.each do |stack| - installer = LanguagePack::Installers::HerokuRubyInstaller.new(stack) - ruby_version = LanguagePack::RubyVersion.new("ruby-#{LanguagePack::RubyVersion::DEFAULT_VERSION_NUMBER}") - installer.fetch_unpack(ruby_version, "vendor/ruby/#{stack}") - end - run! "tar czf #{tmp_dir.join('.buildpack.tgz')} *" - end - - tar_destination = @dest_directory.join("heroku-buildpack-ruby-#{@version}.tgz") - @io.puts "Writing to #{tar_destination}" - - FileUtils.cp(tmp_dir.join('.buildpack.tgz'), tar_destination) - end - end - - private def run!(cmd) - out = `#{cmd}` - raise "Command: #{cmd} was expected to succeed but it did not. Output: #{out}" unless $?.success? - out - end -end diff --git a/spec/rake/deploy_check_spec.rb b/spec/rake/deploy_check_spec.rb index b9f97ae39..c2c85b0a9 100644 --- a/spec/rake/deploy_check_spec.rb +++ b/spec/rake/deploy_check_spec.rb @@ -139,9 +139,9 @@ def deploy.remote_tag_array; [ "v123" ] ; end run!("touch CHANGELOG.md") expect { deploy.check_changelog! - }.to raise_error(/Expected CHANGELOG.md to include v999/) + }.to raise_error(/Expected CHANGELOG.md to include \[v999\]/) - run!("echo '## v999' >> CHANGELOG.md") + run!("echo '## [v999]' >> CHANGELOG.md") deploy.check_changelog! end end diff --git a/spec/rake/tarballer_spec.rb b/spec/rake/tarballer_spec.rb deleted file mode 100644 index 89a982e5d..000000000 --- a/spec/rake/tarballer_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -require "spec_helper" -require "rake/tarballer" - -def real_entries(dir) - Dir.entries(dir) - [".", ".."] -end - -describe "tarballer" do - it "blerg" do - Dir.mktmpdir do |dir| - dir = Pathname.new(dir) - run!("echo 'foo' >> #{dir}/foo.txt") - run!("mkdir -p #{dir}/vendor/ruby") - - tarballer = Tarballer.new(name: 'heroku-buildpack-ruby', directory: dir, io: StringIO.new) - tarballer.call(stacks: ["heroku-18"]) - - # Test tar generated - tgz_name = "heroku-buildpack-ruby-#{LanguagePack::Base::BUILDPACK_VERSION}.tgz" - buildpacks_dir = real_entries("#{dir}/buildpacks") - expect(buildpacks_dir).to include(tgz_name) - - # Test tar contents - tgz_file = dir.join("buildpacks", tgz_name) - tar_contents = run!("tar -tvf #{tgz_file}").strip - expect(tar_contents).to include("vendor/ruby/heroku-18/bin/gem") - expect(tar_contents).to include("foo.txt") - end - end -end