-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is the first working version of `keeparelease`.
- Loading branch information
Showing
8 changed files
with
331 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Changelog | ||
|
||
All notable changes to this project will be documented in this file. | ||
|
||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
||
## [Unreleased] | ||
|
||
## [[1.0.0]] - 2019-06-23 | ||
|
||
Initial release. | ||
|
||
[//]: # (Release links) | ||
|
||
|
||
[//]: # (Issue/PR links) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
# keeparelease | ||
Publish beautiful GitHub release with Keep a changelog | ||
|
||
Publish beautiful GitHub release with Keep a changelog. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
|
||
"github.com/github/hub/github" | ||
"github.com/github/hub/ui" | ||
"github.com/github/hub/utils" | ||
|
||
"github.com/rgreinho/keeparelease/keeparelease" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var cfgFile string | ||
|
||
// rootCmd represents the base command when called without any subcommands | ||
var rootCmd = &cobra.Command{ | ||
Use: "keeparelease", | ||
Short: "Create beautiful GitHub releases.", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
// Get the flags. | ||
extract, err := cmd.Flags().GetBool("extract") | ||
utils.Check(err) | ||
|
||
// Read the last release information from the Changelog. | ||
title, content, err := keeparelease.ReadChangelog() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// If extract only, simply display the content of the last release. | ||
if extract { | ||
fmt.Print(content) | ||
return nil | ||
} | ||
|
||
// Inspect the local repo. | ||
localRepo, err := github.LocalRepo() | ||
utils.Check(err) | ||
project, nil := localRepo.MainProject() | ||
utils.Check(err) | ||
|
||
// Prepare the Hub client. | ||
gh := github.NewClient(project.Host) | ||
|
||
// Prepare the release. | ||
tag, err := cmd.Flags().GetString("tag") | ||
params := &github.Release{ | ||
TagName: tag, | ||
Name: title, | ||
Body: content, | ||
} | ||
|
||
// Create the release. | ||
var release *github.Release | ||
release, err = gh.CreateRelease(project, params) | ||
utils.Check(err) | ||
|
||
// Upload assets. | ||
assets, err := cmd.Flags().GetStringArray("attach") | ||
uploadAssets(gh, release, assets) | ||
|
||
return nil | ||
}, | ||
} | ||
|
||
// Execute adds all child commands to the root command and sets flags appropriately. | ||
// This is called by main.main(). It only needs to happen once to the rootCmd. | ||
func Execute() { | ||
if err := rootCmd.Execute(); err != nil { | ||
fmt.Println(err) | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
func init() { | ||
// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.keeparelease.yaml)") | ||
rootCmd.Flags().BoolP("extract", "x", false, "Only extract the last release information") | ||
rootCmd.Flags().StringP("tag", "t", "", "Use a specific tag") | ||
rootCmd.Flags().StringArrayP("attach", "a", []string{}, "Specify the assets to include into the release") | ||
} | ||
|
||
func uploadAssets(gh *github.Client, release *github.Release, assets []string) { | ||
for _, asset := range assets { | ||
var label string | ||
parts := strings.SplitN(asset, "#", 2) | ||
asset = parts[0] | ||
if len(parts) > 1 { | ||
label = parts[1] | ||
} | ||
|
||
for _, existingAsset := range release.Assets { | ||
if existingAsset.Name == filepath.Base(asset) { | ||
err := gh.DeleteReleaseAsset(&existingAsset) | ||
utils.Check(err) | ||
break | ||
} | ||
} | ||
ui.Errorf("Attaching release asset `%s'...\n", asset) | ||
_, err := gh.UploadReleaseAsset(release, asset, label) | ||
utils.Check(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
module github.com/rgreinho/keeparelease | ||
|
||
go 1.12 | ||
|
||
require ( | ||
github.com/BurntSushi/toml v0.3.1 // indirect | ||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect | ||
github.com/github/hub v2.11.1+incompatible | ||
github.com/inconshreveable/mousetrap v1.0.0 // indirect | ||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect | ||
github.com/kr/pretty v0.1.0 // indirect | ||
github.com/lithammer/dedent v1.1.0 | ||
github.com/mattn/go-colorable v0.1.1 // indirect | ||
github.com/mattn/go-isatty v0.0.7 // indirect | ||
github.com/mitchellh/go-homedir v1.1.0 // indirect | ||
github.com/spf13/cobra v0.0.3 | ||
github.com/spf13/pflag v1.0.3 // indirect | ||
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac // indirect | ||
gopkg.in/yaml.v2 v2.2.2 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= | ||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= | ||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= | ||
github.com/github/hub v2.11.1+incompatible h1:z/Sy79RwOBJtDCX2dwWJliYHTjVRx0BHEEsQ3I6cTOY= | ||
github.com/github/hub v2.11.1+incompatible/go.mod h1:zQrzJEdze2hfWJDgktd/L6sROjAdCThFrzjbxw4keTs= | ||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= | ||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= | ||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= | ||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= | ||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= | ||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= | ||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= | ||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||
github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= | ||
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= | ||
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= | ||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= | ||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= | ||
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= | ||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= | ||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= | ||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= | ||
github.com/rgreinho/keeparelease v0.0.0-20190620004850-206ea132e078 h1:CFHFrdOhBQ/f5Qfo3aH7gGtb/bC9pwMcInrh0zCK0xE= | ||
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= | ||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= | ||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= | ||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | ||
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac h1:7d7lG9fHOLdL6jZPtnV4LpI41SbohIJ1Atq7U991dMg= | ||
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= | ||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= | ||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package keeparelease | ||
|
||
import ( | ||
"errors" | ||
"io/ioutil" | ||
"regexp" | ||
"strings" | ||
) | ||
|
||
const regexTitle string = `^\#\#\s+\[{1,2}(?P<full_version>(?P<major>(?:0|[1-9][0-9]*))\.(?P<minor>(?:0|[1-9][0-9]*))\.(?P<patch>(?:0|[1-9][0-9]*))(\-(?P<prerelease>(?:0|[1-9A-Za-z-][0-9A-Za-z-]*)(\.(?:0|[1-9A-Za-z-][0-9A-Za-z-]*))*))?(\+(?P<build>[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?)\]{1,2}\s+-?\s+(?P<date>.*)` | ||
|
||
// ParseChangelog parses a ChangeLog respecting the Keep A Changelog format. | ||
func ParseChangelog(changelog []string) (string, string, error) { | ||
re := regexp.MustCompile(regexTitle) | ||
title := "" | ||
releaseInfo := make([]string, 1) | ||
foundStart := false | ||
for _, line := range changelog { | ||
|
||
// Look for a release line. | ||
if re.MatchString(line) { | ||
if !foundStart { | ||
|
||
// Indicate we found the first line of the last release information. | ||
foundStart = true | ||
match := re.FindStringSubmatch(line) | ||
result := make(map[string]string) | ||
for i, name := range re.SubexpNames() { | ||
if i != 0 && name != "" { | ||
result[name] = match[i] | ||
} | ||
} | ||
|
||
// Add title line. | ||
title = result["full_version"] | ||
continue | ||
|
||
} else { | ||
// We reached the last line of the last release information. | ||
break | ||
} | ||
} | ||
if foundStart { | ||
// Ensure the first line is followed by a blank line. | ||
if len(releaseInfo) == 1 && line != "" { | ||
releaseInfo = append(releaseInfo, "") | ||
} | ||
|
||
// Append the content. | ||
releaseInfo = append(releaseInfo, line) | ||
} | ||
} | ||
if len(releaseInfo) == 0 { | ||
return "", "", errors.New("could not extract release information") | ||
} | ||
|
||
return title, strings.Join(releaseInfo, "\n"), nil | ||
} | ||
|
||
// ReadChangelog reads the changelog file. | ||
func ReadChangelog() (string, string, error) { | ||
dat, err := ioutil.ReadFile("CHANGELOG.md") | ||
if err != nil { | ||
return "", "", err | ||
} | ||
content := string(dat) | ||
title, info, err := ParseChangelog(strings.Split(content, "\n")) | ||
if err != nil { | ||
return "", "", err | ||
} | ||
return title, info, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package keeparelease | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
|
||
"github.com/lithammer/dedent" | ||
) | ||
|
||
const changelog string = ` | ||
# Changelog | ||
All notable changes to this project will be documented in this file. | ||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
## [Unreleased] | ||
## [[0.4.0]] - 2018-09-07 | ||
### Added | ||
- A feature | ||
### Fixed | ||
- A fix | ||
## [[0.3.0]] - 2018-09-05 | ||
### Added | ||
- Make the Git operations idempotent. | ||
- Implement all the operations required to create an environment. | ||
- Create an Octopus client to simplify the operation using its REST API. | ||
- Add --dry-run flag to bypass the write operations. | ||
[//]: # (Release links) | ||
[0.3.0]: https://github.com/shipstation/hyperion/releases/tag/0.3.0 | ||
[0.4.0]: https://github.com/shipstation/hyperion/releases/tag/0.4.0 | ||
[//]: # (Issue/PR links) | ||
[#15]: https://github.com/shipstation/hyperion/pull/15 | ||
[#16]: https://github.com/shipstation/hyperion/pull/16 | ||
` | ||
|
||
func TestParseChangelog00(t *testing.T) { | ||
title, content, err := ParseChangelog(strings.Split(changelog, "\n")) | ||
if err != nil { | ||
t.Fatalf("failed to parse the changelog: %s", err) | ||
} | ||
expected := ` | ||
### Added | ||
- A feature | ||
### Fixed | ||
- A fix | ||
` | ||
|
||
if dedent.Dedent(title) != dedent.Dedent("0.4.0") { | ||
t.Fatalf("Error: title is %s, but expected is 0.4.0", title) | ||
} | ||
if dedent.Dedent(content) != dedent.Dedent(expected) { | ||
t.Fatalf("Error: actual is %s, but expected is %s", content, expected) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package main | ||
|
||
import "github.com/rgreinho/keeparelease/cmd" | ||
|
||
func main() { | ||
cmd.Execute() | ||
} |