def test_get_releases_skips_objects_with_invalid_data(): s3 = boto3.resource("s3") client = boto3.client("s3") s3.create_bucket(Bucket="test") bucket = s3.BucketVersioning("test") bucket.enable() # missing fields client.put_object( Bucket="test", Key="test-app", Body=json.dumps({ "changelog": "some changes", "image": "sha256:eb1494dee949e52c20084672700c9961d7fc99d1be1c07b5492bc61c3b22a460", "author": "*****@*****.**", }), ) # invalid JSON client.put_object(Bucket="test", Key="test-app", Body='{ "this": "is" invalid') with freeze_time("2018-02-02T00:00:00"): new = client.put_object( Bucket="test", Key="test-app", Body=json.dumps({ "version": 2, "commit": "abcdef0123456789", "changelog": "some other changes to fix version 1", "image": "sha256:000dd6d0c34dd4bb2ec51316ec41f723dd546ef79b30e551ec8390d032707351", "author": "*****@*****.**", }), ) rs = release.get_releases(client, "test-app", bucket="test") expected = [ release.Release( version=2, commit="abcdef0123456789", changelog="some other changes to fix version 1", version_id=new["VersionId"], image= "sha256:000dd6d0c34dd4bb2ec51316ec41f723dd546ef79b30e551ec8390d032707351", timestamp=datetime(2018, 2, 2, 0, 0, 0, tzinfo=pytz.utc), author="*****@*****.**", ) ] compare(expected, list(rs))
def test_get_releases_no_releases_yet(): s3 = boto3.resource("s3") client = boto3.client("s3") s3.create_bucket(Bucket="test") bucket = s3.BucketVersioning("test") bucket.enable() rs = release.get_releases(client, "test-app", bucket="test") compare([], list(rs))
def current(_, name, env, bucket=None, profile=None): """ Show current running version. """ client = utils.s3_client(profile) if bucket is None: bucket = utils.get_config()["deploy"][env]["s3_bucket"] last_deploy = next(get_releases(client, name, bucket=bucket), None) if last_deploy: utils.printfmt(last_deploy) else: utils.fatal("Release does not exist")
def start( _, name, env, version=None, bucket=None, dry=False, yes=False, rollback=False, profile=None, ): """ Deploy a release on an environment. """ client = utils.s3_client(profile) repo = utils.git_repo() if version is None: release = next(get_releases(client, name), None) else: release = get_release(client, name, int(version)) if release is None: utils.fatal("Release not found") if bucket is None: bucket = utils.get_config()["deploy"][env]["s3_bucket"] last_deploy = next(get_releases(client, name, bucket=bucket), None) last_deployed_version = int(last_deploy.version) if last_deploy else 0 if version is not None: since = min(int(version), last_deployed_version) else: since = last_deployed_version releases = list(get_releases(client, name, since=since)) # the field `commits` is not present in all documents as it was introduced # in a later version. if any of the releases doesn't track them, we'll # skip the commit filtering to avoid not showing commits in the changelog. if any(rel.commits is None for rel in releases): commits = None else: commits = [ commit for rel in releases if rel.commits for commit in rel.commits ] if last_deploy is None: # first deploy is always None changelog = utils.changelog(repo, release.commit, None, keep_only_commits=commits) changelog_text = changelog.short_text is_rollback = release.rollback else: # create a changelog from the latest deploy commit changelog = utils.changelog( repo, git.Oid(hex=release.commit), git.Oid(hex=last_deploy.commit), keep_only_commits=commits, ) changelog_text = changelog.short_text is_rollback = changelog.rollback action_type = ActionType.automated if config.IS_CONCOURSE else ActionType.manual release = dataclasses.replace( release, changelog=changelog_text, timestamp=datetime.now(), author=utils.get_author(repo, git.Oid(hex=release.commit)), rollback=is_rollback, action_type=action_type, commits=commits, ) utils.printfmt(release) if dry: return if release.rollback: commit_count = len(changelog.logs) utils.warning(":warning: This is a rollback! :warning:\n") utils.warning( f":warning: You are rolling back from {name} v{last_deployed_version} to v{version} :warning:\n" ) utils.warning( f":warning: This will remove the above {commit_count} commits from {env} :warning:\n" ) if not rollback: utils.error("Missing flag --rollback\n") utils.fatal("Aborted!") if not yes: if release.rollback: ok = utils.confirm( "Are you sure you want to start a rollback deployment?", style=utils.TextStyle.yellow, ) if not ok: utils.fatal("Aborted!") ok = utils.confirm("Are you sure you want to start this deployment?") if not ok: utils.fatal("Aborted!") put_release(client, bucket, name, release) utils.success("Started new deployment :rocket:\n")
def start(_, name, env, version=None, bucket=None, dry=False, yes=False, rollback=False): """ Deploy a release on an environment. """ client = utils.s3_client() repo = utils.git_repo() if version is None: release = next(get_releases(client, name), None) else: release = get_release(client, name, int(version)) if release is None: LOG.critical("Release not found") sys.exit(1) if bucket is None: bucket = utils.get_config()["deploy"][env]["s3_bucket"] last_deploy = next(get_releases(client, name, bucket=bucket), None) if last_deploy is None: # first deploy is always None changelog_text = release.changelog is_rollback = release.rollback else: # create a changelog from the latest deploy commit changelog = utils.changelog(repo, release.commit, last_deploy.commit) changelog_text = changelog.text is_rollback = changelog.rollback release = dataclasses.replace( release, changelog=changelog_text, timestamp=datetime.now(), author=utils.get_author(repo), rollback=is_rollback, ) utils.printfmt(release) if dry: return if release.rollback: utils.warning("This is a rollback! :warning:\n") if not rollback: utils.warning("Missing flag --rollback\n") utils.error("Aborted!\n") sys.exit(1) if not yes: if release.rollback: ok = utils.confirm( "Are you sure you want to start a rollback deployment?", style=utils.TextStyle.warning, ) if not ok: utils.error("Aborted!\n") sys.exit(1) ok = utils.confirm("Are you sure you want to start this deployment?") if not ok: utils.error("Aborted!\n") sys.exit(1) put_release(client, bucket, name, release) utils.success("Started new deployment :rocket:\n")
def test_get_releases_since(): s3 = boto3.resource("s3") client = boto3.client("s3") s3.create_bucket(Bucket="test") bucket = s3.BucketVersioning("test") bucket.enable() with freeze_time("2018-01-01T12:00:00"): client.put_object( Bucket="test", Key="test-app", Body=json.dumps({ "version": 1, "commit": "0123456789abcdef", "changelog": "some changes", "image": "sha256:eb1494dee949e52c20084672700c9961d7fc99d1be1c07b5492bc61c3b22a460", "author": "*****@*****.**", }), ) with freeze_time("2018-02-02T00:00:00"): second = client.put_object( Bucket="test", Key="test-app", Body=json.dumps({ "version": 2, "commit": "abcdef0123456789", "changelog": "some other changes to fix version 1", "image": "sha256:000dd6d0c34dd4bb2ec51316ec41f723dd546ef79b30e551ec8390d032707351", "author": "*****@*****.**", }), ) with freeze_time("2018-03-03T00:00:00"): third = client.put_object( Bucket="test", Key="test-app", Body=json.dumps({ "version": 3, "commit": "zxcvbnm12345", "changelog": "new awesome feature", "image": "sha256:b0190de683bc5d190c4c09473e0d2a5696850f22244cd8e9fc925117580b6361", "author": "*****@*****.**", }), ) rs = release.get_releases(client, "test-app", since=2, bucket="test") expected = [ release.Release( version=3, commit="zxcvbnm12345", changelog="new awesome feature", version_id=third["VersionId"], image= "sha256:b0190de683bc5d190c4c09473e0d2a5696850f22244cd8e9fc925117580b6361", timestamp=datetime(2018, 3, 3, 0, 0, 0, tzinfo=pytz.utc), author="*****@*****.**", ), release.Release( version=2, commit="abcdef0123456789", changelog="some other changes to fix version 1", version_id=second["VersionId"], image= "sha256:000dd6d0c34dd4bb2ec51316ec41f723dd546ef79b30e551ec8390d032707351", timestamp=datetime(2018, 2, 2, 0, 0, 0, tzinfo=pytz.utc), author="*****@*****.**", ), ] compare(expected, list(rs))