From f94897f13e0ee594af4e589cb1c52d192ccbc991 Mon Sep 17 00:00:00 2001
From: Ryan Blunden
Date: Tue, 21 May 2019 11:46:02 -0700
Subject: [PATCH] Updated release blog post template and added script for
generating contributors.
Contributors = non-Sourcegraphers that raised an issue.
---
.gitignore | 1 +
RELEASE_BLOG_POST_TEMPLATE.md | 22 +++----
bin/generate_contributors.go | 113 ++++++++++++++++++++++++++++++++++
go.mod | 9 +++
go.sum | 14 +++++
5 files changed, 146 insertions(+), 13 deletions(-)
create mode 100644 bin/generate_contributors.go
create mode 100644 go.mod
create mode 100644 go.sum
diff --git a/.gitignore b/.gitignore
index 3c50f31b6e4..cc06534d484 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
yarn.lock
.yarn-integrity
docs/server/config/site.md
+.idea
diff --git a/RELEASE_BLOG_POST_TEMPLATE.md b/RELEASE_BLOG_POST_TEMPLATE.md
index 2ba85fc8125..64bd1267d74 100644
--- a/RELEASE_BLOG_POST_TEMPLATE.md
+++ b/RELEASE_BLOG_POST_TEMPLATE.md
@@ -22,7 +22,9 @@ Vimeo embed
-->
-We're excited to announce Sourcegraph {VERSION}. Sourcegraph is a code search and navigation tool (self-hosted, open-source, and cross-repository). Read on for the details, and thanks to our customers and community for reporting issues and providing feedback. You’re helping to make each Sourcegraph release the best one yet!
+[Sourcegraph](https://about.sourcegraph.com/) is the standard developer platform for code search and navigation at many of the largest and most exacting technology companies. With Sourcegraph, every company can get access to the same kind of tools that Google and Facebook developers use every day.
+
+We're excited to announce Sourcegraph {VERSION}. This release makes Sourcegraph more flexible and configurable to meet the needs of [our large enterprise customers](https://about.sourcegraph.com/), such as Uber, Lyft and Yelp. Our customers rely on Sourcegraph to search across 30,000+ repositories, with 1,000s of daily users on single instances.
@@ -37,14 +39,12 @@ Sourcegraph couldn’t be what it is without the community.
+**Deploy or upgrade:** [Local](https://docs.sourcegraph.com/#quickstart-guide) | [AWS](https://github.com/sourcegraph/deploy-sourcegraph-aws) | [DigitalOcean](https://marketplace.digitalocean.com/apps/sourcegraph?action=deploy&refcode=48dfb3ccb51c) | [Kubernetes cluster](https://github.com/sourcegraph/deploy-sourcegraph)
+
## New feature
New feature section. Good if you have screenshots or diagrams and even better if you have a screencast.
-**Deploy or upgrade:** [Local](https://docs.sourcegraph.com/#quickstart-guide) | [AWS](https://github.com/sourcegraph/deploy-sourcegraph-aws) | [DigitalOcean](https://marketplace.digitalocean.com/apps/sourcegraph?action=deploy&refcode=48dfb3ccb51c) | [Kubernetes cluster](https://github.com/sourcegraph/deploy-sourcegraph)
-
-**Insiders:** Want to try pre-release development builds? Change the Docker image tag to `sourcegraph:insiders`.
-
## {VERSION} Changelog
-
-## Deploy or upgrade
-
-[Local](https://docs.sourcegraph.com/#quickstart-guide) | [AWS](https://github.com/sourcegraph/deploy-sourcegraph-aws) | [DigitalOcean](https://marketplace.digitalocean.com/apps/sourcegraph?action=deploy&refcode=48dfb3ccb51c) | [Kubernetes cluster](https://github.com/sourcegraph/deploy-sourcegraph)
+ Generate the list of people who contributed to this release (created issues) by copying the output from bin/generate_contributors.go:
-Upgrading from 2.x or 3.0? [See the migration guide](https://docs.sourcegraph.com/admin/migration/3_0)
+ Usage: GO111MODULE=on go run bin/generate_contributors.go
+-->
----
+**Deploy or upgrade:** [Local](https://docs.sourcegraph.com/#quickstart-guide) | [AWS](https://github.com/sourcegraph/deploy-sourcegraph-aws) | [DigitalOcean](https://marketplace.digitalocean.com/apps/sourcegraph?action=deploy&refcode=48dfb3ccb51c) | [Kubernetes cluster](https://github.com/sourcegraph/deploy-sourcegraph)
From the entire Sourcegraph team ([@srcgraph](https://twitter.com/srcgraph)), happy coding!
diff --git a/bin/generate_contributors.go b/bin/generate_contributors.go
new file mode 100644
index 00000000000..f37cf0e2e86
--- /dev/null
+++ b/bin/generate_contributors.go
@@ -0,0 +1,113 @@
+// Generate a list of non-Sourcegraph contributors for this release
+//
+// Usage: GO111MODULE=on go run bin/generate_contributors.go
+//
+
+package main
+
+import (
+ "bufio"
+ "context"
+ "fmt"
+ "log"
+ "os"
+ "time"
+
+ "github.com/google/go-github/github" // with go modules enabled (GO111MODULE=on or outside GOPATH)
+ "golang.org/x/oauth2"
+)
+
+type IssueAuthorDetails struct {
+ handle string
+ url string
+}
+
+func main() {
+ ctx := context.Background()
+ ts := oauth2.StaticTokenSource(
+ &oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")},
+ )
+ tc := oauth2.NewClient(ctx, ts)
+ client := github.NewClient(tc)
+ repos := [...]string{"deploy-sourcegraph", "lang-typescript", "sourcegraph", "about", "go-langserver", "lang-go", "lang-python", "sourcegraph-basic-code-intel", "python-language-server"}
+
+ // Date of last release
+ fmt.Print("Last release date (yyyy-mm-dd): ")
+ dateInput, _ := bufio.NewReader(os.Stdin).ReadString('\n')
+ lastReleaseDate := fmt.Sprintf("%s%s", dateInput[:len(dateInput)-1], "T12:00:00.000Z")
+
+ // (HACK): Generate list of Sourcegraphers to exclude from the list of contributors
+ //
+ // To manually re-generate the `sourcegraphers` map:
+ // Go to https://github.com/orgs/sourcegraph/teams/team/members
+ // Run this code in the console
+ //
+ // let sourcegraphers = [];
+ // window.document.querySelectorAll('li.table-list-item').forEach(
+ // el => sourcegraphers.push(`"${el.dataset.bulkActionsId.trim()}": "",`)
+ // )
+ // copy(`sourcegraphers := map[string]string{\n${sourcegraphers.join('\n ')}\n}`)
+ //
+ // TODO: Replace with API call as part of the running of this script
+ sourcegraphers := map[string]string{
+ "ryan-blunden": "",
+ "felixfbecker": "",
+ "attfarhan": "",
+ "vanesa": "",
+ "nicksnyder": "",
+ "lguychard": "",
+ "sqs": "",
+ "renovate[bot]": "",
+ "keegancsmith": "",
+ "beyang": "",
+ "chrismwendt": "",
+ "dadlerj": "",
+ "ggilmore": "",
+ "KattMingMing": "",
+ "slimsag": "",
+ "tsenart": "",
+ "kevinzliu": "",
+ "ijt": "",
+ "renovate": "",
+ "bot": "",
+ "todo": "",
+ }
+
+ issueDate, err := time.Parse(time.RFC3339, lastReleaseDate)
+ if err != nil {
+ log.Fatal("error parsing date", err)
+ return
+ }
+ contributors := make(map[string]IssueAuthorDetails)
+ page := 0
+
+ // First print via repo
+ for _, repo := range repos {
+
+ for page < 15 {
+ opts := &github.IssueListByRepoOptions{Since: issueDate, ListOptions: github.ListOptions{PerPage: 100, Page: page}}
+ issues, _, err := client.Issues.ListByRepo(ctx, "sourcegraph", repo, opts)
+ if err != nil {
+ log.Fatal("error fetching repo", err)
+ return
+ }
+
+ if len(issues) == 0 {
+ break
+ }
+
+ for _, issue := range issues {
+ if _, ok := sourcegraphers[*issue.User.Login]; ok {
+ continue
+ }
+
+ contributors[*issue.User.Login] = IssueAuthorDetails{handle: *issue.User.Login, url: *issue.User.HTMLURL}
+ }
+ page++
+ }
+ }
+
+ for _, contributor := range contributors {
+ fmt.Println(fmt.Sprintf("- [@%s](%s)", contributor.handle, contributor.url))
+ }
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 00000000000..314aa0a395c
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,9 @@
+module github.com/sourcegraph/about
+
+go 1.12
+
+require (
+ github.com/google/go-github v17.0.0+incompatible // indirect
+ github.com/google/go-querystring v1.0.0 // indirect
+ golang.org/x/oauth2 v0.0.0-20190517181255-950ef44c6e07 // indirect
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 00000000000..b79c24dc651
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,14 @@
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
+github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
+github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
+github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/oauth2 v0.0.0-20190517181255-950ef44c6e07 h1:XC1K3wNjuz44KaI+cj85C9TW85w/46RH7J+DTXNH5Wk=
+golang.org/x/oauth2 v0.0.0-20190517181255-950ef44c6e07/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=