def check_pre_conditions_for_publish(self) -> None: if self.details.push_to_production: self.check_pre_conditions_for_main_repo() PrepareStarterProjectRelease.check_pre_conditions_for_starter_project_repo( self.details) run([ "open", F"{self.details.project_details.github_project_url}/commits/master" ]) check_step("the builds are passing") run([ "open", F"{self.details.project_details.github_project_url}/blob/master/build/relnotes_x.y.z.md" ]) run([ "open", F"{self.details.project_details.github_project_url}/compare/{self.details.old_version.get_version_text()}...master" ]) check_step("the release notes are ready") run([ "open", F"{self.details.project_details.github_project_url}/issues" ]) check_step("any issues resolved in this release are closed") run([ "open", F"{self.details.project_details.github_project_url}/milestones" ]) check_step( "the milestone (if any) is up to date, including actual version number of release" )
def test_conan_and_create_pr(details: ReleaseDetails) -> None: with use_directory( os.path.join(ConanReleaseDetails().conan_approvaltests_dir, 'all')): # We cannot test the new Conan recipe until the new release has been # published on github new_version_without_v = details.new_version.get_version_text_without_v( ) run(['conan', 'create', '.', F'{new_version_without_v}@']) check_step( F"Commit the changes - with message 'Add approvaltests.cpp {new_version_without_v}'" ) check_step( 'Push the changes - NB on the feature branch for the release') new_branch = PrepareConanRelease.get_new_branch_name( details.new_version) run([ "open", F'https://github.com/conan-io/conan-center-index/compare/master...claremacrae:{new_branch}?expand=1' ]) description = F'** approvaltests.cpp / {new_version_without_v} **' pyperclip.copy(description) print( F"Create a pull request, including this at the start of the description (which is on your clipboard): {description}" ) check_step( "that you have created a Pull Request for conan-center-index?")
def create_pull_request(details: ReleaseDetails) -> None: accepted = details.old_version.get_version_text_without_v( ) in PrepareConanRelease.get_accepted_approval_releases( details.project_details) if not accepted: print( F'Previous version number {details.old_version.get_version_text_without_v()} not found in list of ' F'accepted releases. Not prompting to create a Pull Request.') return new_version_without_v = details.new_version.get_version_text_without_v( ) new_branch = PrepareConanRelease.get_new_branch_name( details.project_details, details.new_version) run([ "open", F'https://github.com/conan-io/conan-center-index/compare/master...claremacrae:{new_branch}?expand=1' ]) description = F'**{details.project_details.conan_directory_name}/{new_version_without_v}**' pyperclip.copy(description) print( F"Create a pull request, including this at the start of the description (which is on your clipboard): {description}" ) check_step( "that you have created a Pull Request for conan-center-index?")
def check_pre_conditions_for_publish(self) -> None: if self.details.push_to_production: repo = Repo(release_constants.main_project_dir) assert_step(not repo.bare) assert_step((repo.active_branch.name == 'master')) GitUtilities.check_no_uncommitted_changes(repo) # From https://stackoverflow.com/questions/15849640/how-to-get-count-of-unpublished-commit-with-gitpython assert_step(len( list(repo.iter_commits('master@{u}..master'))) == 0, "there are un-pushed changes in ApprovalTests.cpp") run(["open", "https://github.com/approvals/ApprovalTests.cpp/commits/master"]) check_step("the builds are passing") run(["open", "https://github.com/approvals/ApprovalTests.cpp/blob/master/build/relnotes_x.y.z.md"]) run(["open", F"https://github.com/approvals/ApprovalTests.cpp/compare/{self.details.old_version.get_version_text()}...master"]) check_step("the release notes are ready") run(["open", "https://github.com/approvals/ApprovalTests.cpp/issues"]) check_step("any issues resolved in this release are closed") run(["open", "https://github.com/approvals/ApprovalTests.cpp/milestones"]) check_step("the milestone (if any) is up to date, including actual version number of release")
def publish_tweet(self) -> None: # Draft the tweet check_step( "that you have created a screenshot of the release notes, for the Tweet" ) tweet_text = self.get_tweet_text() run(["open", tweet_text]) check_step("that the tweet is published")
def reset_and_clean_working_directory(project_dir: str) -> None: with use_directory(project_dir): # Delete untracked files: # - does not delete ignored files # - does not delete untracked files in new, untracked directories run(["git", "clean", "-f"]) run(["git", "reset", "--hard"])
def publish_tweet(self) -> None: # Draft the tweet check_step( "that you have created a screenshot of the release notes, for the Tweet" ) tweet_text = F"'https://twitter.com/intent/tweet?text=%23ApprovalTests.cpp+{self.details.new_version_as_text()}+released%2C+now+with+___%21%0D%0Ahttps%3A%2F%2Fgithub.com%2Fapprovals%2FApprovalTests.cpp%2Freleases%2Ftag%2F{self.details.new_version_as_text()}+%0D%0Aor+try+the+starter+project%3A+https%3A%2F%2Fgithub.com%2Fapprovals%2FApprovalTests.cpp.StarterProject%0D%0AThanks+%40LlewellynFalco+%40ClareMacraeUK+%21'" run(["open", tweet_text]) check_step("that the tweet is published")
def publish_starter_project(self) -> None: self.commit_starter_project() self.push_starter_project() run([ "open", "https://github.com/approvals/ApprovalTests.cpp.StarterProject/commits/master" ]) check_step("that the starter project is published")
def upload_release_to_github(self) -> None: # Draft the upload to github release_notes = read_file(self.details.new_release_notes_path) pyperclip.copy(release_notes) print('The release notes are on the clipboard') github_url = F"'https://github.com/approvals/ApprovalTests.cpp/releases/new?tag={self.details.new_version_as_text()}&title=Single%20Hpp%20File%20-%20{self.details.new_version_as_text()}'" run(["open", github_url]) run(["open", release_constants.release_dir]) check_step("that the release is published")
def upload_release_to_github(self) -> None: # Draft the upload to github release_notes = read_file(self.details.new_release_notes_path) pyperclip.copy(release_notes) print('The release notes are on the clipboard') github_url = self.get_github_release_url() run(["open", github_url]) run(["open", release_constants.release_dir]) check_step("that the release is published")
def test_conan_build_passes(conan_details: ConanReleaseDetails, version_without_v: str) -> None: conan_directory = os.path.join(conan_details.conan_approvaltests_dir, 'all') with use_directory(conan_directory): run([ 'conan', 'create', '--build=missing', '.', F'{version_without_v}@' ])
def update_vcpkg_version_files(details: ReleaseDetails, commit_message: str) -> None: run(["brew", "install", "vcpkg"]) run([ "vcpkg", "x-add-version", f"--vcpkg-root={details.vcpkg_details.vcpkg_repo_dir}", details.project_details.vcpkg_directory_name ]) GitUtilities.add_and_commit_everything( details.vcpkg_details.vcpkg_repo_dir, commit_message)
def add() -> None: run(["git", "add", "."])
def revert() -> None: run(["git", "clean", "-fx"]) run(["git", "reset", "--hard"])
def check_starter_project_builds(self) -> None: with use_directory( F"{release_constants.starter_project_dir}/cmake-build-debug"): run(["cmake", "--build", "."])
def publish_on_reddit_optionally(self) -> None: # Announce on Reddit - maybe? run(["open", "https://www.reddit.com/r/cpp/"]) check_step("if you want to announce this on Reddit r/cpp")
def push_main_project(self) -> None: with use_directory(self.details.locations.main_project_dir): run(["git", "push", "origin", "master"])
def test_typehints(self) -> None: set_home_directory() pushdir('../build') run(['./check_type_hints.sh']) popdir()
def commit_everything(directory: str, message: str) -> None: with use_directory(directory): run(["git", "commit", "-m", F"'{message}'"])
def commit_main_project(self) -> None: with use_directory(release_constants.main_project_dir): run([ "git", "commit", "-m", F"'{self.details.new_version_as_text()} release'" ])
def push_main_project(self) -> None: with use_directory(release_constants.main_project_dir): run(["git", "push", "origin", "master"])
def commit_starter_project(self) -> None: with use_directory(release_constants.starter_project_dir): run([ "git", "commit", "-m", F"'Update to Approvals {self.details.new_version_as_text()}'" ])
def add_everything(directory: str) -> None: with use_directory(directory): run(["git", "add", "."])
def check_starter_project_builds(self) -> None: with use_directory(F"{self.details.locations.starter_project_dir}/cmake-build-debug"): run(["cmake", "--build", "."])
def publish_to_maven(details: ReleaseDetails) -> None: new = details.new_version.get_version_text_without_v() run(["mvn", "versions:set", f"-DnewVersion={new}"]) run(["./publish_maven.sh"])
def push_starter_project(details: ReleaseDetails) -> None: with use_directory(details.locations.starter_project_dir): run(["git", "push", "origin", "master"])
def regenerate_markdown() -> None: with use_directory(".."): run(["./run_markdown_templates.sh"])
def check_starter_project_builds(details: ReleaseDetails) -> None: build_dir = F"{details.locations.starter_project_dir}/cmake-build-validate-release" ensure_directory_exists(build_dir) with use_directory(build_dir): run(["cmake", ".."]) run(["cmake", "--build", "."])
def update_conan_to_latest() -> None: run(["pip3", "install", "--upgrade", "conan"])
def set_snapshot(details: ReleaseDetails) -> None: next_version = details.new_version.update_patch().get_version_text_without_v() run(["mvn", "versions:set", f"-DnewVersion={next_version}-SNAPSHOT"])