App-GitHooks-Plugin-NotifyReleasesToSlack

 view release on metacpan or  search on metacpan

lib/App/GitHooks/Plugin/NotifyReleasesToSlack.pm  view on Meta::CPAN


The path to the changelog file, relative to the root of the repository.

For example, if the changelog file is named C<Changes> and lives at the root of
your repository:

	changelog_path = Changes


=head2 notify_everyone

Whether @everyone in the Slack channel(s) should be notified or not. C<true> by
default, but can be set to C<false> to simply announce releases in the channel
without notification.

	# Notify @everyone in the channel.
	notify_everyone = true

	# Just announce in the channel.
	notify_everyone = false


=head1 METHODS

=head2 run_pre_push()

Code to execute as part of the pre-push hook.

  my $plugin_return_code = App::GitHooks::Plugin::NotifyReleasesToSlack->run_pre_push(
		app   => $app,
		stdin => $stdin,
	);

Arguments:

=over 4

=item * $app I<(mandatory)>

An C<App::GitHooks> object.

=item * $stdin I<(mandatory)>

The content provided by git on stdin, corresponding to a list of references
being pushed.

=back

=cut

sub run_pre_push
{
	my ( $class, %args ) = @_;
	my $app = delete( $args{'app'} );
	my $stdin = delete( $args{'stdin'} );
	my $config = $app->get_config();

	$log->info( 'Entering NotifyReleasesToSlack.' );

	# Verify that the mandatory config options are present.
	my $config_return = verify_config( $config );
	return $config_return
		if defined( $config_return );

	# Check if we are pushing any tags.
	my @tags = get_pushed_tags( $app, $stdin );
	$log->infof( "Found %s tag(s) to push.", scalar( @tags ) );
	if ( scalar( @tags ) == 0 )
	{
		$log->info( "No tags were found in the list of references to push." );
		return $PLUGIN_RETURN_SKIPPED;
	}

	# Get the list of releases in the changelog.
	my $releases = get_changelog_releases( $app );
	$log->infof( "Found %s release(s) in the changelog file.", scalar( keys %$releases ) );

	# Determine the name of the repository.
	my $remote_name = get_remote_name( $app );
	$log->infof( "The repository's remote name is %s.", $remote_name );

	# Determine if we should just announce releases in a normal message, or
	# notify everyone in each channel.
	my $notify_everyone = $config->get( 'NotifyReleasesToSlack', 'notify_everyone' );
	$notify_everyone = defined( $notify_everyone ) && ( $notify_everyone eq 'false' )
		? 0
		: 1;

	# Analyze tags.
	foreach my $tag ( @tags )
	{
		# Check if there's an entry in the changelog.
		my $release = $releases->{ $tag };
		if ( !defined( $release ) )
		{
			$log->infof( "No release found in the changelog for tag '%s'.", $tag );
			next;
		}
		$log->infof( "Found release notes for %s.", $tag );

		# Serialize release notes.
		my $serialized_notes = join(
			"\n",
			map { $_->serialize() } $release->group_values()
		);

		# Notify Slack.
		notify_slack(
			$app,
			sprintf(
				"*%sRelease %s of %s:*\n%s",
				$notify_everyone
					? '<!everyone> - '
					: '',
				$tag,
				$remote_name,
				$serialized_notes,
			),
		);
	}

	return $PLUGIN_RETURN_PASSED;
}


=head1 FUNCTIONS

=head2 verify_config()

Verify that the mandatory options are defined in the current githooksrc config.

	my $plugin_return_code = App::GitHooks::Plugin::NotifyReleasesToSlack::verify_config(
		$config
	);

Arguments:

=over 4

=item * $config I<(mandatory)>

An C<App::GitHooks::Config> object.

=back

=cut

sub verify_config
{
	my ( $config ) = @_;

	# Check if a Slack post url is defined in the config.
	my $slack_post_url = $config->get( 'NotifyReleasesToSlack', 'slack_post_url' );
	if ( !defined( $slack_post_url ) )
	{
		$log->info('No Slack post URL defined in the [NotifyReleasesToSlack] section, skipping plugin.');
		return $PLUGIN_RETURN_SKIPPED;
	}

	# Check if Slack channels are defined in the config.
	my $slack_channels = $config->get( 'NotifyReleasesToSlack', 'slack_channels' );
	if ( !defined( $slack_channels ) )
	{
		$log->info('No Slack channels to post to defined in the [NotifyReleasesToSlack] section, skipping plugin.');
		return $PLUGIN_RETURN_SKIPPED;
	}

	# Check if a changelog is defined in the config.
	my $changelog_path = $config->get( 'NotifyReleasesToSlack', 'changelog_path' );
	if ( !defined( $changelog_path ) )
	{
		$log->info( "'changelog_path' is not defined in the [NotifyReleasesToSlack] section of your .githooksrc config." );
		return $PLUGIN_RETURN_SKIPPED;
	}

	# If notify_everyone is set, make sure the value is valid.
	my $notify_everyone = $config->get( 'NotifyReleasesToSlack', 'notify_everyone' );
	if ( defined( $notify_everyone ) && ( $notify_everyone !~ /(?:true|false)/ ) )
	{
		my $error = "'notify_everyone' is defined in [NotifyReleasesToSlack] but the value is not valid";
		$log->error( "$error." );
		die "$error\n";
	}

	return undef;
}


=head2 get_remote_name()

Get the name of the repository.

	my $remote_name = App::GitHooks::Plugin::NotifyReleasesToSlack::get_remote_name(
		$app
	);

Arguments:

=over 4

=item * $app I<(mandatory)>

An C<App::GitHooks> object.

=back

=cut



( run in 0.937 second using v1.01-cache-2.11-cpan-39bf76dae61 )