def build_deb(repository, release, user, all_releases, linux_host, output_dir): """ Builds a .deb package in docker, and copies it to the host. Args: repository: The github repository to use. username/repo release: The release object from github user: The github user information. Required for changelog information all_releases: All releases from github. Used for generating a changelog linux_host: If set, the docker host ot use that can run linux containers If not None, this should be a format that would work with docker -H output_dir: The directory to place artifacts in after the build Returns: The path to the artifact """ release_version, release_timestamp = get_version_and_timestamp_from_release(release) release_datetime = dateutil.parser.parse(release["created_at"]) image_tag = "buck:" + release_version deb_name = "buck.{}_all.deb".format(release_version) deb_path = os.path.join(output_dir, deb_name) logging.info("Building debian docker image...") # Move the in-repo changelog out of the way for the moment. We keep the file in # repo so that the build rules evaluate properly and don't complain about missing # srcs. changelog_path = os.path.join( "tools", "release", "platforms", "debian", "Changelog" ) changelog = create_changelog(user, all_releases, release_datetime) with temp_move_file(changelog_path), temp_file_with_contents( changelog_path, changelog ): docker( linux_host, [ "build", "-t", image_tag, "--build-arg", "version=" + release_version, "--build-arg", "timestamp=" + str(release_timestamp), "--build-arg", "repository=" + repository, "tools/release/platforms/debian", ], ) logging.info("Copying deb out of docker container") copy_from_docker_linux(linux_host, image_tag, "/src/buck.deb", deb_path) logging.info("Validating that .deb installs...") validate(linux_host, image_tag, deb_path) logging.info("Built .deb file at {}".format(deb_path)) return deb_path
def build_chocolatey(repository, release, windows_host, output_dir): """ Builds a .nupkg package in docker, and copies it to the host. Args: repository: The github repository to use. username/repo release: The release object from github windows_host: If set, the docker host ot use that can run windows containers If not None, this should be a format that would work with docker -H output_dir: The directory to place artifacts in after the build Returns: The path to the artifact """ release_version, release_timestamp = get_version_and_timestamp_from_release(release) image_tag = "buck:" + release_version nupkg_name = "buck.{}.nupkg".format(release_version) nupkg_path = os.path.join(output_dir, nupkg_name) # Get the changelog from github rather than locally changelog_path = os.path.join( "tools", "release", "platforms", "chocolatey", "Changelog.md" ) changelog = release["body"].strip() or "Periodic release" with temp_move_file(changelog_path), temp_file_with_contents( changelog_path, changelog ): logging.info("Building windows docker image...") docker( windows_host, [ "build", "-m", "2g", # Default memory is 1G "-t", image_tag, "--build-arg", "version=" + release_version, "--build-arg", "timestamp=" + str(release_timestamp), "--build-arg", "repository=" + repository, "tools/release/platforms/chocolatey", ], ) logging.info("Copying nupkg out of docker container") copy_from_docker_windows(windows_host, image_tag, "/src/buck.nupkg", nupkg_path) logging.info("Validating that .nupkg installs...") validate(windows_host, image_tag, nupkg_path) logging.info("Built .nupkg file at {}".format(nupkg_path)) return nupkg_path
def validate_tap(homebrew_dir, tap_repository, version): logging.info("Validating that brew installs with new tap information") brew_target = tap_repository + "/buck" brew(homebrew_dir, ["uninstall", "--force", brew_target]) with temp_move_file("/usr/local/bin/buck") as moved: brew(homebrew_dir, ["install", brew_target]) output = (brew( homebrew_dir, ["info", brew_target], capture_output=True).stdout.decode("utf-8").splitlines()[0]) if moved: brew(homebrew_dir, ["uninstall", brew_target]) if "{}/buck: stable {}".format(tap_repository, version) not in output: raise ReleaseException( "Expected version {} to be installed, but got this from `brew info {}`: {}" .format(version, tap_repository, output))
def validate_tap(homebrew_dir, tap_repository, version): logging.info("Validating that brew installs with new tap information") brew_target = tap_repository + "/buck" brew(homebrew_dir, ["uninstall", "--force", brew_target]) with temp_move_file("/usr/local/bin/buck") as moved: brew(homebrew_dir, ["install", brew_target]) output = ( brew(homebrew_dir, ["info", brew_target], capture_output=True) .stdout.decode("utf-8") .splitlines()[0] ) if moved: brew(homebrew_dir, ["uninstall", brew_target]) if "{}/buck: stable {}".format(tap_repository, version) not in output: raise ReleaseException( "Expected version {} to be installed, but got this from `brew info {}`: {}".format( version, tap_repository, output ) )
def build_bottle_file( homebrew_dir, tap_repository, tap_path, release_version, target_macos_version, output_dir, ): """ Builds the actual bottle file via brew Args: tap_repository: The name of the tap repository tap_path: The local path to the given tap repository release_version: The version that should be built (no "v" prefix) target_macos_version: The target macos short nameto use in the resulting path output_dir: The directory to move the build artifact to after building Returns: The path to the bottle.tar.gz """ brew_target = tap_repository + "/buck" # So, if buck wasn't linked to begin with, we can't unlink it. Ideally the install # fails down the road. There is, so far as I could tell, no way to verify if # a formula is linked :/ logging.info("Unlinking buck") brew(homebrew_dir, ["unlink", brew_target], tap_path, check=False) logging.info("Building bottle") # If there is still a buck file that exists, move it out of the way for now # This should generally not be an issue outside of FB with temp_move_file("/usr/local/bin/buck") as moved: # Cool, so install --force will still not rebuild. Uninstall, and just don't # care if the uninstall fails brew( homebrew_dir, ["uninstall", "--force", "--build-bottle", brew_target], tap_path, check=False, ) brew( homebrew_dir, ["install", "--force", "--build-bottle", brew_target], tap_path, ) logging.info("Creating bottle file") brew( homebrew_dir, ["bottle", "--no-rebuild", "--skip-relocation", brew_target], tap_path, ) logging.info("Created bottle file") if moved: # Make sure to unlink again so that we can move the original file back logging.info("Unlinking buck again") brew(homebrew_dir, ["unlink", brew_target], tap_path) bottle_filename = "buck-{ver}.{macos_ver}.bottle.tar.gz".format( ver=release_version, macos_ver=target_macos_version) bottle_path = os.path.join(output_dir, bottle_filename) bottles = glob.glob( os.path.join(tap_path, "buck--{}*.bottle.tar.gz".format(release_version))) if len(bottles) != 1: raise ReleaseException( "Got an invalid number of bottle files ({} files: {})".format( len(bottles), " ".join(bottles))) shutil.move(bottles[0], bottle_path) return bottle_path
def build_bottle_file( homebrew_dir, tap_repository, tap_path, release_version, target_macos_version, output_dir, ): """ Builds the actual bottle file via brew Args: tap_repository: The name of the tap repository tap_path: The local path to the given tap repository release_version: The version that should be built (no "v" prefix) target_macos_version: The target macos short nameto use in the resulting path output_dir: The directory to move the build artifact to after building Returns: The path to the bottle.tar.gz """ brew_target = tap_repository + "/buck" # So, if buck wasn't linked to begin with, we can't unlink it. Ideally the install # fails down the road. There is, so far as I could tell, no way to verify if # a formula is linked :/ logging.info("Unlinking buck") brew(homebrew_dir, ["unlink", brew_target], tap_path, check=False) logging.info("Building bottle") # If there is still a buck file that exists, move it out of the way for now # This should generally not be an issue outside of FB with temp_move_file("/usr/local/bin/buck") as moved: # Cool, so install --force will still not rebuild. Uninstall, and just don't # care if the uninstall fails brew( homebrew_dir, ["uninstall", "--force", "--build-bottle", brew_target], tap_path, check=False, ) brew( homebrew_dir, ["install", "--force", "--build-bottle", brew_target], tap_path, ) logging.info("Creating bottle file") brew( homebrew_dir, ["bottle", "--no-rebuild", "--skip-relocation", brew_target], tap_path, ) logging.info("Created bottle file") if moved: # Make sure to unlink again so that we can move the original file back logging.info("Unlinking buck again") brew(homebrew_dir, ["unlink", brew_target], tap_path) bottle_filename = "buck-{ver}.{macos_ver}.bottle.tar.gz".format( ver=release_version, macos_ver=target_macos_version ) bottle_path = os.path.join(output_dir, bottle_filename) bottles = glob.glob( os.path.join(tap_path, "buck--{}*.bottle.tar.gz".format(release_version)) ) if len(bottles) != 1: raise ReleaseException( "Got an invalid number of bottle files ({} files: {})".format( len(bottles), " ".join(bottles) ) ) shutil.move(bottles[0], bottle_path) return bottle_path