Skip to content

Commit

Permalink
feat: announce: reddit (#2431)
Browse files Browse the repository at this point in the history
* feat: announce: reddit

Signed-off-by: Batuhan Apaydın <batuhan.apaydin@trendyol.com>

* Update .goreleaser.yml

* Update internal/pipe/announce/announce.go

* Update pkg/defaults/defaults.go

Co-authored-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
  • Loading branch information
developer-guy and caarlos0 committed Aug 31, 2021
1 parent 5e906b2 commit d3db692
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 0 deletions.
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
2 changes: 2 additions & 0 deletions internal/pipe/announce/announce.go
Expand Up @@ -4,6 +4,7 @@ package announce
import (
"fmt"

"github.com/goreleaser/goreleaser/internal/pipe/reddit"
"github.com/goreleaser/goreleaser/internal/middleware"
"github.com/goreleaser/goreleaser/internal/pipe/twitter"
"github.com/goreleaser/goreleaser/pkg/context"
Expand All @@ -26,6 +27,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
2 changes: 2 additions & 0 deletions pkg/defaults/defaults.go
Expand Up @@ -5,6 +5,7 @@ package defaults
import (
"fmt"

"github.com/goreleaser/goreleaser/internal/pipe/reddit"
"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 +58,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!''
```

1 comment on commit d3db692

@vercel
Copy link

@vercel vercel bot commented on d3db692 Aug 31, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.