App-Gitc
view release on metacpan or search on metacpan
bin/gitc-promote view on Meta::CPAN
to_undo { git "checkout $target" };
git "branch -D $target" if not $integration_branch_existed;
to_undo { git "branch $target $integrate" };
git "push origin $integrate:$target @tag_refs";
};
# integrate with Eventum. failing here is not worth rolling back
if (@new_tags) {
my $tag_name = pop @new_tags;
my @changesets = map { m{^cs/([^/]+)/to-} ? $1 : () } @new_tags;
my $all = join ', ', @changesets;
my $project = project_name();
my %seen;
for my $cs (@changesets) {
my $its = its_for_changeset($cs);
if ($its) {
my $its_name = $its->label_service;
my $issue = $its->get_issue($cs) or next;
# only update each issue once
next if $seen{ $its->issue_number($issue) }++;
eval {
my $what_happened = $its->transition_state({
command => 'promote',
issue => $issue,
target => $target,
message => "Promoted $project#$cs to $target "
. "($tag_name) along with $all",
changeset => $cs,
});
warn $what_happened;
};
warn "$its_name Error: ".$@ if $@;
}
}
# prevent trivial conflicts for the next 'gitc pass'
if ( $cherry_pick and $target eq project_config()->{ open_onto } ) {
git "fetch origin";
git "checkout master" if $original_branch ne 'master';
git "reset --hard origin/master";
git "merge -s ours origin/$target";
git "push origin master";
git "checkout -f $original_branch" if $original_branch ne 'master';
}
}
# reinstate any changes present when we started
git "stash apply $stash" if $stash;
########################## helper subs ###########################
# determine what we're promoting and where
sub parse_command_line {
my @argv = @_;
# extract structure from the command line
my $target = pop @argv;
my @changesets = grep { !/^-/ } @argv;
# validate the promotion target
die "You must specify a promotion target\n" if not $target;
die "Invalid promotion target '$target'\n"
if not defined environment_preceding($target);
# validate changesets
my $refs = validate_changesets( $target, @changesets );
return ( $target, $refs, \@changesets );
}
# checks a list of changeset names for sanity. dies on anything bad.
# if the changesets are ok, it returns an arrayref of Git refs for
# those changesets
sub validate_changesets {
my ( $target, @changesets ) = @_;
return ( $target, [] ) if not @changesets;
die "You may not cherry pick promote to prod\n"
if !$force and $target eq 'prod' and @changesets;
warn "Validating changesets\n";
my @refs;
my @already_promoted;
my %seen;
for my $changeset (@changesets) {
die "You may not cherry pick '$changeset' to $target\n"
if $changeset =~ m/^(master|test|stage|prod)$/;
die "You asked to promote '$changeset' twice. Did you mean\n"
. "to list it once or did you mistype some other changeset?\n"
if $seen{$changeset}++;
push @refs, full_changeset_name($changeset);
push @already_promoted, $changeset
if is_valid_ref("cs/$changeset/to-$target");
}
if (@already_promoted) {
my $msg = "These changesets have already been promoted to $target:\n";
$msg .= " - $_\n" for @already_promoted;
die $msg;
}
return \@refs;
}
# quickly locate any changeset dependencies that were not explicitly listed.
# takes a promotion target and a list of refs to promote.
# returns a list of the refs for those dependencies
sub find_missing_dependencies {
my ( $target, @wanted ) = @_;
my @extras = map { full_changeset_name($_) }
unpromoted( \@wanted, "origin/$target" );
# find refs that weren't explicitly listed
my %extras = map { ( $_ => 1 ) } @extras;
delete @extras{@wanted};
return keys %extras;
}
# given a list of requested changeset refs and a list of missing dependency
# refs, prompts the user what to do and returns a new list of requested
# changeset refs
sub handle_missing_dependencies {
my ( $wanted, $missing ) = @_;
my @pretty = map { short_ref_name($_) } @$missing;
sort_changesets_by_name(\@pretty);
warn "The following changeset dependencies are missing:\n";
warn " - $_\n" for @pretty;
die "Exiting promotion because of missing dependencies\n" if not -t STDIN;
print STDERR 'What do you want to do? '
. '(p)romote these too, e(x)it, see (d)etails: ';
chomp ( my $choice = <STDIN> );
if ( $choice eq 'p' ) {
return ( @$wanted, @$missing );
}
elsif ( $choice eq 'd' ) {
warn "\n";
( run in 0.644 second using v1.01-cache-2.11-cpan-39bf76dae61 )