Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: announce: reddit #2431

Merged
merged 4 commits into from Aug 31, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -21,6 +21,7 @@ require (
github.com/spf13/cobra v1.2.1
github.com/stretchr/testify v1.7.0
github.com/ulikunitz/xz v0.5.10
github.com/vartanbeno/go-reddit/v2 v2.0.1
github.com/xanzy/go-gitlab v0.50.3
gocloud.dev v0.23.0
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Expand Up @@ -581,6 +581,8 @@ github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oW
github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8=
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/vartanbeno/go-reddit/v2 v2.0.1 h1:P6ITpf5YHjdy7DHZIbUIDn/iNAoGcEoDQnMa+L4vutw=
github.com/vartanbeno/go-reddit/v2 v2.0.1/go.mod h1:758/S10hwZSLm43NPtwoNQdZFSg3sjB5745Mwjb0ANI=
github.com/xanzy/go-gitlab v0.50.3 h1:M7ncgNhCN4jaFNyXxarJhCLa9Qi6fdmCxFFhMTQPZiY=
github.com/xanzy/go-gitlab v0.50.3/go.mod h1:Q+hQhV508bDPoBijv7YjK/Lvlb4PhVhJdKqXVQrUoAE=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
Expand Down
3 changes: 3 additions & 0 deletions internal/pipe/announce/announce.go
Expand Up @@ -4,6 +4,8 @@ package announce
import (
"fmt"

"github.com/goreleaser/goreleaser/internal/pipe/reddit"

caarlos0 marked this conversation as resolved.
Show resolved Hide resolved
"github.com/goreleaser/goreleaser/internal/middleware"
"github.com/goreleaser/goreleaser/internal/pipe/twitter"
"github.com/goreleaser/goreleaser/pkg/context"
Expand All @@ -26,6 +28,7 @@ type Announcer interface {
// nolint: gochecknoglobals
var announcers = []Announcer{
twitter.Pipe{}, // announce to twitter
reddit.Pipe{}, // announce to twitter
}

// Run the pipe.
Expand Down
83 changes: 83 additions & 0 deletions internal/pipe/reddit/reddit.go
@@ -0,0 +1,83 @@
package reddit

import (
"fmt"

"github.com/apex/log"
"github.com/caarlos0/env/v6"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/vartanbeno/go-reddit/v2/reddit"
)

const (
defaultTitleTemplate = `{{ .ProjectName }} {{ .Tag }} is out!`
defaultURLTemplate = `{{ .GitURL }}/releases/tag/{{ .Tag }}`
)

type Pipe struct{}

func (Pipe) String() string { return "reddit" }

type Config struct {
Secret string `env:"REDDIT_SECRET,notEmpty"`
Password string `env:"REDDIT_PASSWORD,notEmpty"`
}

func (Pipe) Default(ctx *context.Context) error {
if ctx.Config.Announce.Reddit.TitleTemplate == "" {
ctx.Config.Announce.Reddit.TitleTemplate = defaultTitleTemplate
}

if ctx.Config.Announce.Reddit.URLTemplate == "" {
ctx.Config.Announce.Reddit.URLTemplate = defaultURLTemplate
}

return nil
}

func (Pipe) Announce(ctx *context.Context) error {
if ctx.SkipAnnounce {
return pipe.ErrSkipAnnounceEnabled
}
if !ctx.Config.Announce.Reddit.Enabled {
return pipe.ErrSkipDisabledPipe
}

title, err := tmpl.New(ctx).Apply(ctx.Config.Announce.Reddit.TitleTemplate)
if err != nil {
return fmt.Errorf("announce: failed to announce to reddit: %w", err)
}

url, err := tmpl.New(ctx).Apply(ctx.Config.Announce.Reddit.URLTemplate)
if err != nil {
return fmt.Errorf("announce: failed to announce to reddit: %w", err)
}

linkRequest := reddit.SubmitLinkRequest{
Subreddit: ctx.Config.Announce.Reddit.Sub,
Title: title,
URL: url,
}

var cfg Config
if err := env.Parse(&cfg); err != nil {
return fmt.Errorf("announce: failed to announce to reddit: %w", err)
}

credentials := reddit.Credentials{ID: ctx.Config.Announce.Reddit.ApplicationID, Secret: cfg.Secret, Username: ctx.Config.Announce.Reddit.Username, Password: cfg.Password}
client, err := reddit.NewClient(credentials)
if err != nil {
return fmt.Errorf("announce: failed to announce to reddit: %w", err)
}

post, _, err := client.Post.SubmitLink(ctx, linkRequest)
if err != nil {
return fmt.Errorf("announce: failed to announce to reddit: %w", err)
}

log.Infof("announce: The text post is available at: %s\n", post.URL)

return nil
}
74 changes: 74 additions & 0 deletions internal/pipe/reddit/reddit_test.go
@@ -0,0 +1,74 @@
package reddit

import (
"testing"

"github.com/goreleaser/goreleaser/internal/testlib"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
)

func TestStringer(t *testing.T) {
require.Equal(t, Pipe{}.String(), "reddit")
}

func TestDefault(t *testing.T) {
ctx := context.New(config.Project{})
require.NoError(t, Pipe{}.Default(ctx))
require.Equal(t, ctx.Config.Announce.Reddit.TitleTemplate, defaultTitleTemplate)
}

func TestAnnounceDisabled(t *testing.T) {
ctx := context.New(config.Project{})
require.NoError(t, Pipe{}.Default(ctx))
testlib.AssertSkipped(t, Pipe{}.Announce(ctx))
}

func TestAnnounceInvalidURLTemplate(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Reddit: config.Reddit{
Enabled: true,
URLTemplate: "{{ .Foo }",
},
},
})
require.EqualError(t, Pipe{}.Announce(ctx), `announce: failed to announce to reddit: template: tmpl:1: unexpected "}" in operand`)
}

func TestAnnounceInvalidTitleTemplate(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Reddit: config.Reddit{
Enabled: true,
TitleTemplate: "{{ .Foo }",
},
},
})
require.EqualError(t, Pipe{}.Announce(ctx), `announce: failed to announce to reddit: template: tmpl:1: unexpected "}" in operand`)
}

func TestAnnounceMissingEnv(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Reddit: config.Reddit{
Enabled: true,
},
},
})
require.NoError(t, Pipe{}.Default(ctx))
require.EqualError(t, Pipe{}.Announce(ctx), `announce: failed to announce to reddit: env: environment variable "REDDIT_SECRET" should not be empty`)
}

func TestAnnounceSkipAnnounce(t *testing.T) {
ctx := context.New(config.Project{
Announce: config.Announce{
Reddit: config.Reddit{
Enabled: true,
},
},
})
ctx.SkipAnnounce = true
testlib.AssertSkipped(t, Pipe{}.Announce(ctx))
}
10 changes: 10 additions & 0 deletions pkg/config/config.go
Expand Up @@ -690,13 +690,23 @@ type GoMod struct {

type Announce struct {
Twitter Twitter `yaml:"twitter,omitempty"`
Reddit Reddit `yaml:"reddit,omitempty"`
}

type Twitter struct {
Enabled bool `yaml:"enabled,omitempty"`
MessageTemplate string `yaml:"message_template,omitempty"`
}

type Reddit struct {
Enabled bool `yaml:"enabled,omitempty"`
ApplicationID string `yaml:"application_id,omitempty"`
Username string `yaml:"username,omitempty"`
TitleTemplate string `yaml:"title_template,omitempty"`
URLTemplate string `yaml:"url_template,omitempty"`
Sub string `yaml:"sub,omitempty"`
}

// Load config file.
func Load(file string) (config Project, err error) {
f, err := os.Open(file) // #nosec
Expand Down
3 changes: 3 additions & 0 deletions pkg/defaults/defaults.go
Expand Up @@ -5,6 +5,8 @@ package defaults
import (
"fmt"

"github.com/goreleaser/goreleaser/internal/pipe/reddit"

caarlos0 marked this conversation as resolved.
Show resolved Hide resolved
"github.com/goreleaser/goreleaser/internal/pipe/archive"
"github.com/goreleaser/goreleaser/internal/pipe/artifactory"
"github.com/goreleaser/goreleaser/internal/pipe/blob"
Expand Down Expand Up @@ -57,5 +59,6 @@ var Defaulters = []Defaulter{
brew.Pipe{},
scoop.Pipe{},
twitter.Pipe{},
reddit.Pipe{},
milestone.Pipe{},
}
32 changes: 32 additions & 0 deletions www/docs/customization/announce.md
Expand Up @@ -32,3 +32,35 @@ announce:

!!! tip
Learn more about the [name template engine](/customization/templates/).

## Reddit

For it to work, you'll need to [create a new Reddit app](https://www.reddit.com/prefs/apps), and set some environment variables on your pipeline:

- `REDDIT_SECRET`
- `REDDIT_PASSWORD`

Then, you can add something like the following to your `.goreleaser.yml` config:

```yaml
# .goreleaser.yml
announce:
reddit:
# Wether its enabled or not.
# Defaults to false.
enabled: true

# Application ID for Reddit Application
application_id: ""

# Username for your Reddit account
username: ""

# URL template to use while publishing.
# Defaults to `{{ .GitURL }}/releases/tag/{{ .Tag }}`
url_template: 'https://github.com/goreleaser/goreleaser/releases/tag/{{ .Tag }}'

# Title template to use while publishing.
# Defaults to `{{ .ProjectName }} {{ .Tag }} is out!`
title_template: ''GoReleaser {{ .Tag }} was just released!''
```