You've already forked go-semantic-release
Compare commits
36 Commits
1.0.0-rc.0
...
v1.2.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1342714579 | ||
|
|
d92438b339 | ||
|
|
aff2203d66 | ||
|
|
113ddf2b1f | ||
|
|
8e3c446605 | ||
|
|
8ea92efb90 | ||
|
|
42fc522a43 | ||
|
|
6211095c38 | ||
|
|
74e895b5ad | ||
|
|
a69da92340 | ||
|
|
ff87725801 | ||
|
|
272a9b6e89 | ||
|
|
07b606a21a | ||
|
|
44f95969bf | ||
|
|
399a3515f2 | ||
|
|
2074877a3b | ||
|
|
b5551d8432 | ||
|
|
c92020d3ac | ||
|
|
d9f2b163c7 | ||
|
|
4379551982 | ||
|
|
3eb13972ec | ||
|
|
8659b40960 | ||
|
|
7ead374039 | ||
|
|
ee1dc3d8db | ||
|
|
38e4c178ee | ||
|
|
e22d3d07f4 | ||
|
|
46ae2da821 | ||
|
|
e3265b1843 | ||
|
|
d03913e6d7 | ||
|
|
e5ed8edb75 | ||
|
|
76ffeda95b | ||
|
|
0994354089 | ||
|
|
e8d7feeca3 | ||
|
|
e0974e3140 | ||
|
|
8643656339 | ||
|
|
829f2925ab |
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!build/
|
||||
64
.github/workflows/main.yml
vendored
64
.github/workflows/main.yml
vendored
@@ -1,39 +1,51 @@
|
||||
name: Go
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Go 1.13
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: 1.13
|
||||
id: go
|
||||
|
||||
- name: Set up Go 1.12
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: 1.12
|
||||
id: go
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v1
|
||||
- name: Lint
|
||||
run: |
|
||||
export PATH=$PATH:$(go env GOPATH)/bin
|
||||
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.18.0
|
||||
golangci-lint run ./...
|
||||
|
||||
- name: Lint
|
||||
run: |
|
||||
export PATH=$PATH:$(go env GOPATH)/bin
|
||||
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.16.0
|
||||
golangci-lint run ./...
|
||||
- name: Run tests
|
||||
run: go test ./...
|
||||
|
||||
- name: Run tests
|
||||
run: go test ./...
|
||||
- name: Build binary
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
go build -o build/go-semantic-release-temp ./cmd/go-semantic-release/
|
||||
./build/go-semantic-release-temp next --no-cache --loglevel trace
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o build/go-semantic-release -ldflags "-w -s --X main.version=`./build/go-semantic-release-temp next`" ./cmd/go-semantic-release/
|
||||
GOOS=windows GOARCH=386 CGO_ENABLED=0 go build -o build/go-semantic-release.exe -ldflags "-w -s -X main.version=`./build/go-semantic-release-temp next`" ./cmd/go-semantic-release/
|
||||
|
||||
- name: Build binary
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
go build -o build/go-semantic-release-temp ./cmd/go-semantic-release/
|
||||
go build -o build/go-semantic-release -ldflags "-w -s --X main.version=`./build/go-semantic-release-temp next`" ./cmd/go-semantic-release/
|
||||
GOOS=windows GOARCH=386 go build -o build/go-semantic-release.exe -ldflags "-w -s -X main.version=`./build/go-semantic-release-temp next`" ./cmd/go-semantic-release/
|
||||
- name: Build Docker image
|
||||
if: github.ref != 'refs/heads/master'
|
||||
run: |
|
||||
docker build -t nightapes/go-semantic-release:development .
|
||||
docker login -u nightapes -p ${{ secrets.DOCKER_PASSWORD }}
|
||||
docker push nightapes/go-semantic-release:development
|
||||
|
||||
- name: Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: ./build/go-semantic-release-temp release --loglevel trace
|
||||
- name: Push Docker image
|
||||
if: github.ref != 'refs/heads/master'
|
||||
run: |
|
||||
|
||||
- name: Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
docker login -u nightapes -p ${{ secrets.DOCKER_PASSWORD }}
|
||||
./build/go-semantic-release-temp release --loglevel trace
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -16,3 +16,5 @@ go-semantic-release
|
||||
.vscode/settings.json
|
||||
CHANGELOG.md
|
||||
cover.html
|
||||
build/
|
||||
.idea/
|
||||
|
||||
27
.release.yml
27
.release.yml
@@ -1,18 +1,23 @@
|
||||
release: "github"
|
||||
github:
|
||||
repo: "go-semantic-release"
|
||||
user: "nightapes"
|
||||
commitFormat: angular
|
||||
title: "go-semantic-release release"
|
||||
branch:
|
||||
master: rc
|
||||
changelog:
|
||||
printAll: false
|
||||
template: ''
|
||||
templatePath: ''
|
||||
release: 'github'
|
||||
master: release
|
||||
assets:
|
||||
- name: ./build/go-semantic-release
|
||||
compress: false
|
||||
- name: ./build/go-semantic-release.exe
|
||||
compress: false
|
||||
github:
|
||||
repo: "go-semantic-release"
|
||||
user: "nightapes"
|
||||
customUrl: ""
|
||||
changelog:
|
||||
docker:
|
||||
latest: true
|
||||
repository: "nightapes/go-semantic-release"
|
||||
hooks:
|
||||
preRelease:
|
||||
- docker build -t nightapes/go-semantic-release:latest .
|
||||
- docker build -t nightapes/go-semantic-release:$RELEASE_VERSION .
|
||||
postRelease:
|
||||
- docker push nightapes/go-semantic-release:latest
|
||||
- docker push nightapes/go-semantic-release:$RELEASE_VERSION
|
||||
|
||||
9
Dockerfile
Normal file
9
Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
||||
FROM alpine:3.10.2
|
||||
|
||||
WORKDIR /code
|
||||
|
||||
COPY ./build/go-semantic-release .
|
||||
|
||||
USER 1000
|
||||
|
||||
ENTRYPOINT [ "./go-semantic-release" ]
|
||||
219
README.md
219
README.md
@@ -2,24 +2,217 @@
|
||||
|
||||
## Release Types
|
||||
|
||||
| Type | Git tag | Changelog | Release | Write access git | Api token |
|
||||
|--- |:---: |:---: |:---: |:---: |:---: |
|
||||
| `git` | :white_check_mark: | | | :white_check_mark:| |
|
||||
| `github` | :white_check_mark: | :white_check_mark: | :white_check_mark:| | :white_check_mark: |
|
||||
| `gitlab` | :white_check_mark: | :white_check_mark: | :white_check_mark:| | :white_check_mark: |
|
||||
| Type | Implemendet | Git tag | Changelog | Release | Write access git | Api token |
|
||||
| ---------- | :----------------: | :----------------: | :----------------: | :----------------: | :----------------: | :----------------: |
|
||||
| `github` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | :white_check_mark: |
|
||||
| `gitlab` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | :white_check_mark: |
|
||||
| `git` | :white_check_mark: | :white_check_mark: | | | :white_check_mark: | |
|
||||
| `bitbuckt` | Comming soon | :white_check_mark: | | | :white_check_mark: | |
|
||||
|
||||
|
||||
## Supported CI Pipelines
|
||||
|
||||
* Github Actions
|
||||
* Gitlab CI
|
||||
* Travis CI
|
||||
* Custom CI, set enviroment `CI=true`
|
||||
|
||||
## How to use
|
||||
|
||||
`go-semantic-release` config file
|
||||
Create a file with the name `.release.yml` or anything else, but you need to set to every command `-c <your config file>`
|
||||
|
||||
### Example config
|
||||
|
||||
```yml
|
||||
commitFormat: angular
|
||||
branch:
|
||||
master: release
|
||||
release: 'github'
|
||||
github:
|
||||
repo: "go-semantic-release"
|
||||
user: "nightapes"
|
||||
assets:
|
||||
- name: ./build/go-semantic-release
|
||||
compress: false
|
||||
- name: ./build/go-semantic-release.exe
|
||||
compress: false
|
||||
hooks:
|
||||
preRelease:
|
||||
- name: echo $RELEASE_VERSION
|
||||
postRelease:
|
||||
- name: echo $RELEASE_VERSION
|
||||
```
|
||||
|
||||
#### CommitFormat
|
||||
|
||||
Set the commit format, at the moment we support ony [angular](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit-message-format), more coming soon.
|
||||
|
||||
```yml
|
||||
commitFormat: angular
|
||||
```
|
||||
|
||||
#### Branch
|
||||
|
||||
You can define which kind of release should be created for different branches.
|
||||
|
||||
Supported release kinds:
|
||||
|
||||
* `release` -> `v1.0.0`
|
||||
* `rc` -> `v1.0.0-rc.0`
|
||||
* `beta` -> `v1.0.0-beta.0`
|
||||
* `alpha` -> `v1.0.0-alpha.0`
|
||||
|
||||
Add a branch config to your config
|
||||
|
||||
```yml
|
||||
branch:
|
||||
<branch-name>: <kind>
|
||||
```
|
||||
|
||||
#### Release
|
||||
|
||||
At the moment we support releases to gitlab and github.
|
||||
|
||||
##### Github
|
||||
|
||||
You need to set the env `GITHUB_TOKEN` with an access token.
|
||||
|
||||
```yml
|
||||
release: 'github'
|
||||
github:
|
||||
user: "<user/group"
|
||||
repo: "<repositroyname>"
|
||||
## Optional, if your not using github.com
|
||||
customUrl: <https://your.github>
|
||||
```
|
||||
|
||||
##### Gitlab
|
||||
|
||||
You need to set the env `GITLAB_ACCESS_TOKEN` with an personal access token.
|
||||
|
||||
|
||||
```yml
|
||||
release: 'gitlab'
|
||||
gitlab:
|
||||
repo: "<repositroyname>" ## Example group/project
|
||||
## Optional, if your not using gitlab.com
|
||||
customUrl: <https://your.gitlab>
|
||||
```
|
||||
|
||||
##### Git only
|
||||
|
||||
Only via https at the moment. You need write access to your git repository
|
||||
|
||||
|
||||
```yml
|
||||
release: 'git'
|
||||
git:
|
||||
email: "<email>" # Used for creating tag
|
||||
user: "<user>" : # Used for creating tag and pushing
|
||||
auth: "<token>" # Used for pushing, can be env "$GIT_TOKEN", will be replaced with env
|
||||
```
|
||||
|
||||
|
||||
#### Assets
|
||||
|
||||
You can upload assets to a release
|
||||
|
||||
Support for gitlab and github.
|
||||
If you want, you can let the file be compressed before uploading
|
||||
|
||||
```yml
|
||||
assets:
|
||||
- name: ./build/go-semantic-release
|
||||
compress: false
|
||||
```
|
||||
|
||||
#### Hooks
|
||||
|
||||
Hooks will run when calling `release`. Hooks run only if a release will be triggered.
|
||||
|
||||
#### Changelog
|
||||
|
||||
Following variables can be used for templates:
|
||||
* `Commits` string
|
||||
* `Version` string
|
||||
* `Now` time.Time
|
||||
* `Backtick` string
|
||||
* `HasDocker` bool
|
||||
* `HasDockerLatest` bool
|
||||
* `DockerRepository` string
|
||||
|
||||
```yml
|
||||
changelog:
|
||||
printAll: false ## Print all valid commits to changelog
|
||||
title: "v{{.Version}} ({{.Now.Format "2006-01-02"}})" ## Used for releases (go template)
|
||||
templatePath: "./examples/changelog.tmpl" ## Path to a template file (go template)
|
||||
```
|
||||
|
||||
##### Docker
|
||||
|
||||
You can print a help text for a docker image
|
||||
|
||||
```yml
|
||||
changelog:
|
||||
docker:
|
||||
latest: false ## If you uploaded a latest image
|
||||
repository: ## Your docker repository, which is used for docker run
|
||||
```
|
||||
|
||||
### Version
|
||||
|
||||
`go-semantic-release` has two modes for calcualting the version: automatic or manual.
|
||||
|
||||
#### Automatic
|
||||
|
||||
Version will be calculated on the `next` or `release` command
|
||||
|
||||
#### Manual
|
||||
|
||||
If you don't want that `go-semantic-release` is calculating the version from the commits, you can set the version by hand with
|
||||
following command:
|
||||
|
||||
```bash
|
||||
./go-semantic-release set 1.1.1
|
||||
```
|
||||
|
||||
### Print version
|
||||
|
||||
Print the next version, can be used to add version to your program
|
||||
|
||||
```bash
|
||||
./go-semantic-release next
|
||||
```
|
||||
Example with go-lang
|
||||
|
||||
```bash
|
||||
go build -ldflags "--X main.version=`./go-semantic-release next`"
|
||||
```
|
||||
|
||||
### Create release
|
||||
|
||||
```bash
|
||||
./go-semantic-release release
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Build
|
||||
## Build from source
|
||||
|
||||
`go build ./cmd/go-semantic-release/`
|
||||
```bash
|
||||
go build ./cmd/go-semantic-release/
|
||||
```
|
||||
|
||||
## Run
|
||||
### Testing
|
||||
|
||||
Print the next version
|
||||
```bash
|
||||
go test ./...
|
||||
```
|
||||
|
||||
`./go-semantic-release version next`
|
||||
### Linting
|
||||
|
||||
Set a version
|
||||
|
||||
`./go-semantic-release version set v1.1.1`
|
||||
```
|
||||
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.16.0
|
||||
golangci-lint run ./...
|
||||
```
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
go build ./cmd/main.go && ./main.exe version next --path /f/Repro/ambassador/
|
||||
go build ./cmd/main.go && ./main.exe --loglevel debug version set v1.1.1 --path /f/Repro/ambassador/
|
||||
3
_config.yml
Normal file
3
_config.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
theme: jekyll-theme-cayman
|
||||
plugins:
|
||||
- jemoji
|
||||
@@ -35,7 +35,12 @@ var changelogCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
s, err := semanticrelease.New(readConfig(config), repository)
|
||||
ignoreConfigChecks, err := cmd.Flags().GetBool("no-checks")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s, err := semanticrelease.New(readConfig(config), repository, !ignoreConfigChecks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -30,7 +30,12 @@ var nextCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
s, err := semanticrelease.New(readConfig(config), repository)
|
||||
ignoreConfigChecks, err := cmd.Flags().GetBool("no-checks")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s, err := semanticrelease.New(readConfig(config), repository, !ignoreConfigChecks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -28,7 +28,12 @@ var releaseCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
s, err := semanticrelease.New(readConfig(config), repository)
|
||||
ignoreConfigChecks, err := cmd.Flags().GetBool("no-checks")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s, err := semanticrelease.New(readConfig(config), repository, !ignoreConfigChecks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ func init() {
|
||||
rootCmd.PersistentFlags().StringP("loglevel", "l", "error", "Set loglevel")
|
||||
rootCmd.PersistentFlags().StringP("config", "c", ".release.yml", "Path to config file")
|
||||
rootCmd.PersistentFlags().Bool("no-cache", false, "Ignore cache, don't use in ci build")
|
||||
rootCmd.PersistentFlags().Bool("no-checks", false, "Ignore missing values and envs")
|
||||
}
|
||||
|
||||
func readConfig(file string) *config.ReleaseConfig {
|
||||
|
||||
@@ -26,7 +26,12 @@ var setCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
s, err := semanticrelease.New(readConfig(config), repository)
|
||||
ignoreConfigChecks, err := cmd.Flags().GetBool("no-checks")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s, err := semanticrelease.New(readConfig(config), repository, !ignoreConfigChecks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func init() {
|
||||
|
||||
var zipCmd = &cobra.Command{
|
||||
Use: "zip",
|
||||
Short: "Zip configured artifact from release config",
|
||||
Short: "Zip configured artifact from release config (internal)",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
config, err := cmd.Flags().GetString("config")
|
||||
if err != nil {
|
||||
@@ -23,7 +23,12 @@ var zipCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
s, err := semanticrelease.New(readConfig(config), repository)
|
||||
ignoreConfigChecks, err := cmd.Flags().GetBool("no-checks")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s, err := semanticrelease.New(readConfig(config), repository, !ignoreConfigChecks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
16
examples/changelog.tmpl
Normal file
16
examples/changelog.tmpl
Normal file
@@ -0,0 +1,16 @@
|
||||
# My custom release template v{{$.Version}} ({{.Now.Format "2006-01-02"}})
|
||||
{{ .Commits -}}
|
||||
{{ if .HasDocker}}
|
||||
## Docker image
|
||||
|
||||
New docker image is released under {{$.Backtick}}{{.DockerRepository}}:{{.Version}}{{$.Backtick}}
|
||||
|
||||
### Usage
|
||||
|
||||
{{$.Backtick}}docker run {{.DockerRepository}}:{{.Version}}{{$.Backtick}}
|
||||
{{ if .HasDockerLatest}}
|
||||
or
|
||||
|
||||
{{$.Backtick}}docker run {{.DockerRepository}}:latest{{$.Backtick}}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
3
go.mod
3
go.mod
@@ -1,6 +1,6 @@
|
||||
module github.com/Nightapes/go-semantic-release
|
||||
|
||||
go 1.12
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/Masterminds/semver v1.4.2
|
||||
@@ -8,6 +8,7 @@ require (
|
||||
github.com/google/go-cmp v0.3.0 // indirect
|
||||
github.com/google/go-github/v25 v25.1.3
|
||||
github.com/kevinburke/ssh_config v0.0.0-20190630040420-2e50c441276c // indirect
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/spf13/cobra v0.0.5
|
||||
github.com/stretchr/testify v1.3.0
|
||||
|
||||
5
go.sum
5
go.sum
@@ -55,6 +55,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
||||
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/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
@@ -62,6 +63,7 @@ github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQz
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA=
|
||||
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -72,14 +74,17 @@ github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
|
||||
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
|
||||
|
||||
@@ -22,7 +22,7 @@ const ANGULAR = "angular"
|
||||
|
||||
func newAngular() *angular {
|
||||
return &angular{
|
||||
regex: `(TAG)(?:\((.*)\))?: (.*)`,
|
||||
regex: `^(TAG)(?:\((.*)\))?: (.*)`,
|
||||
log: log.WithField("analyzer", ANGULAR),
|
||||
rules: []Rule{
|
||||
{
|
||||
|
||||
@@ -107,6 +107,11 @@ func TestAngular(t *testing.T) {
|
||||
Author: "me",
|
||||
Hash: "12345667",
|
||||
},
|
||||
shared.Commit{
|
||||
Message: "Merge feat(internal/changelog): my first commit",
|
||||
Author: "me",
|
||||
Hash: "12345667",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
2
internal/cache/cache_test.go
vendored
2
internal/cache/cache_test.go
vendored
@@ -63,7 +63,7 @@ func TestWriteAndReadCache(t *testing.T) {
|
||||
Author: "Author",
|
||||
Hash: "Hash",
|
||||
},
|
||||
ParsedMessage: "add gitlab as relase option",
|
||||
ParsedMessage: "add gitlab as release option",
|
||||
Scope: "releaser",
|
||||
ParsedBreakingChangeMessage: "",
|
||||
Tag: "feat",
|
||||
|
||||
@@ -49,6 +49,11 @@ func (c *Calculator) CalculateNewVersion(commits map[shared.Release][]shared.Ana
|
||||
}
|
||||
case "release":
|
||||
if !firstRelease {
|
||||
if lastVersion.Prerelease() != "" {
|
||||
newVersion, _ := lastVersion.SetPrerelease("")
|
||||
return newVersion
|
||||
}
|
||||
|
||||
if len(commits["major"]) > 0 {
|
||||
return lastVersion.IncMajor()
|
||||
} else if len(commits["minor"]) > 0 {
|
||||
|
||||
@@ -2,6 +2,7 @@ package changelog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
@@ -13,9 +14,7 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const defaultChangelogTitle string = `v{{.Version}} ({{.Now.Format "2006-01-02"}})`
|
||||
const defaultChangelog string = `# v{{$.Version}} ({{.Now.Format "2006-01-02"}})
|
||||
{{ range $index,$commit := .BreakingChanges -}}
|
||||
const defaultCommitList string = `{{ range $index,$commit := .BreakingChanges -}}
|
||||
{{ if eq $index 0 }}
|
||||
## BREAKING CHANGES
|
||||
{{ end}}
|
||||
@@ -30,10 +29,37 @@ introduced by commit:
|
||||
* **{{$.Backtick}}{{$commit.Scope}}{{$.Backtick}}** {{$commit.ParsedMessage}} {{if $.HasURL}} ([{{ printf "%.7s" $commit.Commit.Hash}}]({{ replace $.URL "{{hash}}" $commit.Commit.Hash}})) {{end}}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ end -}}`
|
||||
const defaultChangelogTitle string = `v{{.Version}} ({{.Now.Format "2006-01-02"}})`
|
||||
const defaultChangelog string = `# v{{$.Version}} ({{.Now.Format "2006-01-02"}})
|
||||
{{ .Commits -}}
|
||||
{{ if .HasDocker}}
|
||||
## Docker image
|
||||
|
||||
New docker image is released under {{$.Backtick}}{{.DockerRepository}}:{{.Version}}{{$.Backtick}}
|
||||
|
||||
### Usage
|
||||
|
||||
{{$.Backtick}}docker run {{.DockerRepository}}:{{.Version}}{{$.Backtick}}
|
||||
{{ if .HasDockerLatest}}
|
||||
or
|
||||
|
||||
{{$.Backtick}}docker run {{.DockerRepository}}:latest{{$.Backtick}}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
`
|
||||
|
||||
type changelogContent struct {
|
||||
Commits string
|
||||
Version string
|
||||
Now time.Time
|
||||
Backtick string
|
||||
HasDocker bool
|
||||
HasDockerLatest bool
|
||||
DockerRepository string
|
||||
}
|
||||
|
||||
type commitsContent struct {
|
||||
Commits map[string][]shared.AnalyzedCommit
|
||||
BreakingChanges []shared.AnalyzedCommit
|
||||
Order []string
|
||||
@@ -91,7 +117,7 @@ func (c *Changelog) GenerateChanglog(templateConfig shared.ChangelogTemplateConf
|
||||
}
|
||||
}
|
||||
|
||||
changelogContent := changelogContent{
|
||||
commitsContent := commitsContent{
|
||||
Version: templateConfig.Version,
|
||||
Commits: commitsPerScope,
|
||||
Now: c.releaseTime,
|
||||
@@ -102,16 +128,50 @@ func (c *Changelog) GenerateChanglog(templateConfig shared.ChangelogTemplateConf
|
||||
URL: templateConfig.CommitURL,
|
||||
}
|
||||
|
||||
title, err := generateTemplate(defaultChangelogTitle, changelogContent)
|
||||
changelogContent := changelogContent{
|
||||
Version: templateConfig.Version,
|
||||
Now: c.releaseTime,
|
||||
Backtick: "`",
|
||||
HasDocker: c.config.Changelog.Docker.Repository != "",
|
||||
HasDockerLatest: c.config.Changelog.Docker.Latest,
|
||||
DockerRepository: c.config.Changelog.Docker.Repository,
|
||||
}
|
||||
template := defaultChangelog
|
||||
if c.config.Changelog.TemplatePath != "" {
|
||||
content, err := ioutil.ReadFile(c.config.Changelog.TemplatePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
template = string(content)
|
||||
}
|
||||
|
||||
templateTitle := defaultChangelogTitle
|
||||
if c.config.Changelog.TemplateTitle != "" {
|
||||
templateTitle = c.config.Changelog.TemplateTitle
|
||||
}
|
||||
|
||||
log.Debugf("Render title")
|
||||
renderedTitle, err := generateTemplate(templateTitle, changelogContent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
content, err := generateTemplate(defaultChangelog, changelogContent)
|
||||
|
||||
return &shared.GeneratedChangelog{Title: title, Content: content}, err
|
||||
log.Debugf("Render commits")
|
||||
renderedCommitList, err := generateTemplate(defaultCommitList, commitsContent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Tracef("Commits %s", renderedCommitList)
|
||||
|
||||
changelogContent.Commits = renderedCommitList
|
||||
log.Debugf("Render changelog")
|
||||
renderedContent, err := generateTemplate(template, changelogContent)
|
||||
|
||||
return &shared.GeneratedChangelog{Title: renderedTitle, Content: renderedContent}, err
|
||||
}
|
||||
|
||||
func generateTemplate(text string, values changelogContent) (string, error) {
|
||||
func generateTemplate(text string, values interface{}) (string, error) {
|
||||
|
||||
funcMap := template.FuncMap{
|
||||
"replace": replace,
|
||||
|
||||
@@ -3,10 +3,11 @@ package ci
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Nightapes/go-semantic-release/internal/gitutil"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/Nightapes/go-semantic-release/internal/gitutil"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
//ProviderConfig struct
|
||||
@@ -38,21 +39,27 @@ func ReadAllEnvs() map[string]string {
|
||||
}
|
||||
|
||||
//GetCIProvider get provider
|
||||
func GetCIProvider(gitUtil *gitutil.GitUtil, envs map[string]string) (*ProviderConfig, error) {
|
||||
func GetCIProvider(gitUtil *gitutil.GitUtil, configCheck bool, envs map[string]string) (*ProviderConfig, error) {
|
||||
|
||||
services := []Service{
|
||||
Travis{},
|
||||
GithubActions{},
|
||||
Git{gitUtil: gitUtil}, // GIt must be the last option to check
|
||||
GitlabCI{},
|
||||
Git{gitUtil: gitUtil}, // Git must be the last option to check
|
||||
}
|
||||
|
||||
for _, service := range services {
|
||||
config, err := service.detect(envs)
|
||||
if err == nil {
|
||||
log.Infof("Found CI: %s", config.Name)
|
||||
log.Tracef("Found CI config: %+v", config)
|
||||
return config, nil
|
||||
}
|
||||
log.Debugf("%s", err.Error())
|
||||
}
|
||||
return nil, fmt.Errorf("could not find any CI, if running locally set env CI=true")
|
||||
if configCheck {
|
||||
return nil, fmt.Errorf("could not find any CI, if running locally set env CI=true")
|
||||
|
||||
}
|
||||
return Git{gitUtil: gitUtil}.detect(map[string]string{"CI": "true"})
|
||||
}
|
||||
|
||||
@@ -111,10 +111,23 @@ func TestCi(t *testing.T) {
|
||||
result: &ci.ProviderConfig{IsPR: false, PR: "", PRBranch: "", Branch: "feature-branch-1", Tag: "", Commit: "190bfd6aa60022afd0ef830342cfb07e33c45f37", BuildURL: "", Service: "GithubActions", Name: "GithubActions CI"},
|
||||
hasError: false,
|
||||
},
|
||||
{
|
||||
service: "GitLab CI/CD PR",
|
||||
envs: map[string]string{
|
||||
"GITLAB_CI": "true",
|
||||
"CI_COMMIT_SHA": "190bfd6aa60022afd0ef830342cfb07e33c45f37",
|
||||
"CI_COMMIT_REF_NAME": "master",
|
||||
"CI_COMMIT_TAG": "tag",
|
||||
"CI_PROJECT_URL": "https://my.gitlab.com",
|
||||
"CI_PIPELINE_ID": "1",
|
||||
},
|
||||
result: &ci.ProviderConfig{IsPR: false, PR: "", PRBranch: "", Branch: "master", Tag: "tag", Commit: "190bfd6aa60022afd0ef830342cfb07e33c45f37", BuildURL: "https://my.gitlab.com/pipelines/1", Service: "gitlab", Name: "GitLab CI/CD"},
|
||||
hasError: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, config := range testConfigs {
|
||||
provider, err := ci.GetCIProvider(gitUtilInMemory, config.envs)
|
||||
provider, err := ci.GetCIProvider(gitUtilInMemory, true, config.envs)
|
||||
assert.Equalf(t, config.hasError, err != nil, "Service %s should have error: %t -> %s", config.service, config.hasError, err)
|
||||
assert.Equalf(t, config.result, provider, "Service %s should have provider", config.service)
|
||||
}
|
||||
|
||||
26
internal/ci/gitlab_ci.go
Normal file
26
internal/ci/gitlab_ci.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package ci
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
//GitlabCI struct
|
||||
type GitlabCI struct{}
|
||||
|
||||
//Detect if on GitlabCI
|
||||
func (t GitlabCI) detect(envs map[string]string) (*ProviderConfig, error) {
|
||||
|
||||
if _, exists := envs["GITLAB_CI"]; !exists {
|
||||
return nil, fmt.Errorf("not running on gitlab")
|
||||
}
|
||||
|
||||
return &ProviderConfig{
|
||||
Service: "gitlab",
|
||||
Name: "GitLab CI/CD",
|
||||
Commit: envs["CI_COMMIT_SHA"],
|
||||
Tag: envs["CI_COMMIT_TAG"],
|
||||
BuildURL: envs["CI_PROJECT_URL"] + "/pipelines/" + envs["CI_PIPELINE_ID"],
|
||||
Branch: envs["CI_COMMIT_REF_NAME"],
|
||||
IsPR: false,
|
||||
}, nil
|
||||
}
|
||||
@@ -5,12 +5,15 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/Nightapes/go-semantic-release/internal/shared"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/src-d/go-git.v4"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing/object"
|
||||
"github.com/Nightapes/go-semantic-release/internal/shared"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing/storer"
|
||||
)
|
||||
|
||||
// GitUtil struct
|
||||
@@ -87,7 +90,7 @@ func (g *GitUtil) GetLastVersion() (*semver.Version, string, error) {
|
||||
|
||||
err = gitTags.ForEach(func(p *plumbing.Reference) error {
|
||||
v, err := semver.NewVersion(p.Name().Short())
|
||||
log.Tracef("%+v with hash: %s", p.Target(), p.Hash())
|
||||
log.Tracef("Tag %+v with hash: %s", p.Target(), p.Hash())
|
||||
|
||||
if err == nil {
|
||||
tags = append(tags, v)
|
||||
@@ -139,7 +142,7 @@ func (g *GitUtil) GetCommits(lastTagHash string) ([]shared.Commit, error) {
|
||||
if c.Hash.String() == lastTagHash {
|
||||
log.Debugf("Found commit with hash %s, will stop here", c.Hash.String())
|
||||
foundEnd = true
|
||||
|
||||
return storer.ErrStop
|
||||
}
|
||||
if !foundEnd {
|
||||
log.Tracef("Found commit with hash %s", c.Hash.String())
|
||||
@@ -153,5 +156,9 @@ func (g *GitUtil) GetCommits(lastTagHash string) ([]shared.Commit, error) {
|
||||
return nil
|
||||
})
|
||||
|
||||
return commits, err
|
||||
if err != nil {
|
||||
return commits, errors.Wrap(err, "Could not read commits, check git clone depth in your ci")
|
||||
}
|
||||
|
||||
return commits, nil
|
||||
}
|
||||
|
||||
71
internal/hooks/hooks.go
Normal file
71
internal/hooks/hooks.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package hooks
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/Nightapes/go-semantic-release/internal/shared"
|
||||
"github.com/Nightapes/go-semantic-release/pkg/config"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
//Hooks struct
|
||||
type Hooks struct {
|
||||
version *shared.ReleaseVersion
|
||||
config *config.ReleaseConfig
|
||||
}
|
||||
|
||||
// New hooks struct
|
||||
func New(config *config.ReleaseConfig, version *shared.ReleaseVersion) *Hooks {
|
||||
return &Hooks{
|
||||
config: config,
|
||||
version: version,
|
||||
}
|
||||
}
|
||||
|
||||
// PreRelease runs before creating release
|
||||
func (h *Hooks) PreRelease() error {
|
||||
log.Infof("Run pre release hooks")
|
||||
for _, cmd := range h.config.Hooks.PreRelease {
|
||||
log.Debugf("Run %s", cmd)
|
||||
err := h.runCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PostRelease runs after creating release
|
||||
func (h *Hooks) PostRelease() error {
|
||||
log.Infof("Run post release hooks")
|
||||
for _, cmd := range h.config.Hooks.PostRelease {
|
||||
err := h.runCommand(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Hooks) runCommand(command string) error {
|
||||
|
||||
splittedCmd := strings.Split(strings.ReplaceAll(command, "$RELEASE_VERSION", h.version.Next.Version.String()), " ")
|
||||
|
||||
cmd := exec.Command(splittedCmd[0], splittedCmd[1:]...)
|
||||
|
||||
cmdReader, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(cmdReader)
|
||||
go func() {
|
||||
for scanner.Scan() {
|
||||
log.WithField("cmd", splittedCmd[0]).Infof("%s\n", scanner.Text())
|
||||
}
|
||||
}()
|
||||
|
||||
return cmd.Run()
|
||||
}
|
||||
103
internal/hooks/hooks_test.go
Normal file
103
internal/hooks/hooks_test.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package hooks_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/Nightapes/go-semantic-release/internal/hooks"
|
||||
"github.com/Nightapes/go-semantic-release/internal/shared"
|
||||
"github.com/Nightapes/go-semantic-release/pkg/config"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPreReleaseHooks(t *testing.T) {
|
||||
|
||||
os.Setenv("GO_WANT_HELPER_PROCESS", "1")
|
||||
hooks := hooks.New(&config.ReleaseConfig{
|
||||
Hooks: config.Hooks{
|
||||
PreRelease: []string{
|
||||
"go test -test.run=TestHelperProcess -- " + "$RELEASE_VERSION",
|
||||
},
|
||||
},
|
||||
},
|
||||
&shared.ReleaseVersion{
|
||||
Next: shared.ReleaseVersionEntry{
|
||||
Version: createVersion("1.0.0"),
|
||||
},
|
||||
})
|
||||
err := hooks.PreRelease()
|
||||
assert.NoError(t, err)
|
||||
os.Unsetenv("GO_WANT_HELPER_PROCESS")
|
||||
|
||||
}
|
||||
|
||||
func TestPreReleaseHooksError(t *testing.T) {
|
||||
|
||||
hooks := hooks.New(&config.ReleaseConfig{
|
||||
Hooks: config.Hooks{
|
||||
PreRelease: []string{
|
||||
"exit 1",
|
||||
},
|
||||
},
|
||||
},
|
||||
&shared.ReleaseVersion{
|
||||
Next: shared.ReleaseVersionEntry{
|
||||
Version: createVersion("1.0.0"),
|
||||
},
|
||||
})
|
||||
err := hooks.PreRelease()
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestPostReleaseHooks(t *testing.T) {
|
||||
|
||||
os.Setenv("GO_WANT_HELPER_PROCESS", "1")
|
||||
hooks := hooks.New(&config.ReleaseConfig{
|
||||
Hooks: config.Hooks{
|
||||
PostRelease: []string{
|
||||
"go test -test.run=TestHelperProcess -- " + "$RELEASE_VERSION",
|
||||
},
|
||||
},
|
||||
},
|
||||
&shared.ReleaseVersion{
|
||||
Next: shared.ReleaseVersionEntry{
|
||||
Version: createVersion("1.0.0"),
|
||||
},
|
||||
})
|
||||
err := hooks.PostRelease()
|
||||
assert.NoError(t, err)
|
||||
os.Unsetenv("GO_WANT_HELPER_PROCESS")
|
||||
|
||||
}
|
||||
|
||||
func TestPostReleaseHooksError(t *testing.T) {
|
||||
|
||||
hooks := hooks.New(&config.ReleaseConfig{
|
||||
Hooks: config.Hooks{
|
||||
PostRelease: []string{
|
||||
"exit 1",
|
||||
},
|
||||
},
|
||||
},
|
||||
&shared.ReleaseVersion{
|
||||
Next: shared.ReleaseVersionEntry{
|
||||
Version: createVersion("1.0.0"),
|
||||
},
|
||||
})
|
||||
err := hooks.PostRelease()
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestHelperProcess(t *testing.T) {
|
||||
if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
|
||||
|
||||
return
|
||||
}
|
||||
assert.Contains(t, os.Args, "1.0.0")
|
||||
}
|
||||
|
||||
func createVersion(version string) *semver.Version {
|
||||
ver, _ := semver.NewVersion(version)
|
||||
return ver
|
||||
}
|
||||
101
internal/releaser/git/git.go
Normal file
101
internal/releaser/git/git.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package git
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Nightapes/go-semantic-release/internal/gitutil"
|
||||
"github.com/Nightapes/go-semantic-release/internal/shared"
|
||||
"github.com/Nightapes/go-semantic-release/pkg/config"
|
||||
"gopkg.in/src-d/go-git.v4"
|
||||
gitConfig "gopkg.in/src-d/go-git.v4/config"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing/object"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing/transport/http"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// GITONLY identifer for git interface
|
||||
const GITONLY = "git"
|
||||
|
||||
// Client type struct
|
||||
type Client struct {
|
||||
config *config.GitProvider
|
||||
log *log.Entry
|
||||
git *gitutil.GitUtil
|
||||
}
|
||||
|
||||
// New initialize a new gitRelease
|
||||
func New(config *config.GitProvider, git *gitutil.GitUtil, checkConfig bool) (*Client, error) {
|
||||
|
||||
logger := log.WithField("releaser", GITONLY)
|
||||
|
||||
if config.Email == "" && checkConfig {
|
||||
return nil, fmt.Errorf("git email not set")
|
||||
}
|
||||
|
||||
if config.Username == "" && checkConfig {
|
||||
return nil, fmt.Errorf("git username not set")
|
||||
}
|
||||
|
||||
if !config.SSH && config.Auth == "" && checkConfig {
|
||||
return nil, fmt.Errorf("git auth not set")
|
||||
}
|
||||
|
||||
if config.SSH {
|
||||
return nil, fmt.Errorf("git ssh not supported yet")
|
||||
}
|
||||
|
||||
return &Client{
|
||||
config: config,
|
||||
log: logger,
|
||||
git: git,
|
||||
}, nil
|
||||
}
|
||||
|
||||
//GetCommitURL for git
|
||||
func (g *Client) GetCommitURL() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
//GetCompareURL for git
|
||||
func (g *Client) GetCompareURL(oldVersion, newVersion string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// CreateRelease creates release on remote
|
||||
func (g *Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedChangelog *shared.GeneratedChangelog) error {
|
||||
|
||||
tag := "v" + releaseVersion.Next.Version.String()
|
||||
g.log.Infof("create release with version %s", tag)
|
||||
|
||||
head, err := g.git.Repository.Head()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = g.git.Repository.CreateTag(tag, head.Hash(), &git.CreateTagOptions{Message: "Release " + tag, Tagger: &object.Signature{
|
||||
Name: g.config.Username,
|
||||
Email: g.config.Email,
|
||||
When: time.Now(),
|
||||
}})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
g.log.Infof("Created release")
|
||||
|
||||
return g.git.Repository.Push(&git.PushOptions{
|
||||
Auth: &http.BasicAuth{
|
||||
Username: g.config.Username,
|
||||
Password: g.config.Auth,
|
||||
},
|
||||
RefSpecs: []gitConfig.RefSpec{"refs/tags/*:refs/tags/*"},
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// UploadAssets uploads specified assets
|
||||
func (g *Client) UploadAssets(repoDir string, assets []config.Asset) error {
|
||||
return nil
|
||||
}
|
||||
@@ -29,17 +29,27 @@ type Client struct {
|
||||
}
|
||||
|
||||
// New initialize a new GitHubRelease
|
||||
func New(c *config.GitHubProvider) (*Client, error) {
|
||||
var err error
|
||||
func New(c *config.GitHubProvider, checkConfig bool) (*Client, error) {
|
||||
|
||||
if c.AccessToken, err = util.GetAccessToken("GITHUB_TOKEN"); err != nil {
|
||||
token, err := util.GetAccessToken("GITHUB_TOKEN")
|
||||
if err != nil && checkConfig {
|
||||
return &Client{}, err
|
||||
}
|
||||
c.AccessToken = token
|
||||
ctx := context.Background()
|
||||
httpClient := util.CreateBearerHTTPClient(ctx, c.AccessToken)
|
||||
|
||||
var client *github.Client
|
||||
baseURL := "https://github.com"
|
||||
|
||||
if c.Repo == "" && checkConfig {
|
||||
return nil, fmt.Errorf("github repro is not set")
|
||||
}
|
||||
|
||||
if c.User == "" && checkConfig {
|
||||
return nil, fmt.Errorf("github user is not set")
|
||||
}
|
||||
|
||||
if c.CustomURL == "" {
|
||||
client = github.NewClient(httpClient)
|
||||
} else {
|
||||
@@ -54,7 +64,7 @@ func New(c *config.GitHubProvider) (*Client, error) {
|
||||
context: ctx,
|
||||
baseURL: baseURL,
|
||||
log: log.WithField("releaser", GITHUB),
|
||||
}, err
|
||||
}, nil
|
||||
}
|
||||
|
||||
//GetCommitURL for github
|
||||
@@ -67,26 +77,10 @@ func (g *Client) GetCompareURL(oldVersion, newVersion string) string {
|
||||
return fmt.Sprintf("%s/%s/%s/compare/%s...%s", g.baseURL, g.config.User, g.config.Repo, oldVersion, newVersion)
|
||||
}
|
||||
|
||||
//ValidateConfig for github
|
||||
func (g *Client) ValidateConfig() error {
|
||||
g.log.Debugf("validate GitHub provider config")
|
||||
|
||||
if g.config.Repo == "" {
|
||||
return fmt.Errorf("github Repro is not set")
|
||||
}
|
||||
|
||||
if g.config.User == "" {
|
||||
return fmt.Errorf("github User is not set")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// CreateRelease creates release on remote
|
||||
func (g *Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedChangelog *shared.GeneratedChangelog) error {
|
||||
|
||||
tag := releaseVersion.Next.Version.String()
|
||||
tag := "v" + releaseVersion.Next.Version.String()
|
||||
g.log.Debugf("create release with version %s", tag)
|
||||
|
||||
prerelease := releaseVersion.Next.Version.Prerelease() != ""
|
||||
|
||||
@@ -48,29 +48,6 @@ var testNewClient = []testHelperMethodStruct{
|
||||
},
|
||||
}
|
||||
|
||||
var testHelperMethod = []testHelperMethodStruct{
|
||||
testHelperMethodStruct{config: config.GitHubProvider{
|
||||
Repo: "foo",
|
||||
User: "bar",
|
||||
},
|
||||
valid: true,
|
||||
},
|
||||
|
||||
testHelperMethodStruct{config: config.GitHubProvider{
|
||||
Repo: "",
|
||||
User: "bar",
|
||||
},
|
||||
valid: false,
|
||||
},
|
||||
|
||||
testHelperMethodStruct{config: config.GitHubProvider{
|
||||
Repo: "foo",
|
||||
User: "",
|
||||
},
|
||||
valid: false,
|
||||
},
|
||||
}
|
||||
|
||||
var lastVersion, _ = semver.NewVersion("1.0.0")
|
||||
var newVersion, _ = semver.NewVersion("2.0.0")
|
||||
|
||||
@@ -146,7 +123,7 @@ func TestNew(t *testing.T) {
|
||||
os.Setenv("GITHUB_TOKEN", "XXX")
|
||||
}
|
||||
|
||||
_, err := github.New(&testOject.config)
|
||||
_, err := github.New(&testOject.config, true)
|
||||
assert.Equal(t, testOject.valid, err == nil)
|
||||
|
||||
os.Unsetenv("GITHUB_TOKEN")
|
||||
@@ -157,7 +134,7 @@ func TestNew(t *testing.T) {
|
||||
func TestGetCommitURL(t *testing.T) {
|
||||
os.Setenv("GITHUB_TOKEN", "XX")
|
||||
for _, testOject := range testNewClient {
|
||||
client, _ := github.New(&testOject.config)
|
||||
client, _ := github.New(&testOject.config, false)
|
||||
actualURL := client.GetCommitURL()
|
||||
if testOject.config.CustomURL != "" {
|
||||
expectedURL := fmt.Sprintf("%s/%s/%s/commit/{{hash}}", testOject.config.CustomURL, testOject.config.User, testOject.config.Repo)
|
||||
@@ -175,7 +152,7 @@ func TestGetCommitURL(t *testing.T) {
|
||||
func TestGetCompareURL(t *testing.T) {
|
||||
os.Setenv("GITHUB_TOKEN", "XX")
|
||||
for _, testOject := range testNewClient {
|
||||
client, _ := github.New(&testOject.config)
|
||||
client, _ := github.New(&testOject.config, false)
|
||||
actualURL := client.GetCompareURL("1", "2")
|
||||
if testOject.config.CustomURL != "" {
|
||||
expectedURL := fmt.Sprintf("%s/%s/%s/compare/%s...%s", testOject.config.CustomURL, testOject.config.User, testOject.config.Repo, "1", "2")
|
||||
@@ -190,18 +167,6 @@ func TestGetCompareURL(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestValidateConfig(t *testing.T) {
|
||||
os.Setenv("GITHUB_TOKEN", "XX")
|
||||
for _, testOject := range testHelperMethod {
|
||||
client, _ := github.New(&testOject.config)
|
||||
err := client.ValidateConfig()
|
||||
|
||||
assert.Equal(t, testOject.valid, err == nil)
|
||||
|
||||
}
|
||||
os.Unsetenv("GITHUB_TOKEN")
|
||||
}
|
||||
|
||||
func TestCreateRelease(t *testing.T) {
|
||||
os.Setenv("GITHUB_TOKEN", "XX")
|
||||
|
||||
@@ -209,7 +174,7 @@ func TestCreateRelease(t *testing.T) {
|
||||
if testObejct.valid {
|
||||
server := initHTTPServer(testObejct.requestResponseCode, testObejct.requestResponseBody)
|
||||
testObejct.config.CustomURL = server.URL
|
||||
client, _ := github.New(&testObejct.config)
|
||||
client, _ := github.New(&testObejct.config, false)
|
||||
|
||||
err := client.CreateRelease(testObejct.releaseVersion, testObejct.generatedChangelog)
|
||||
if err != nil {
|
||||
@@ -221,7 +186,7 @@ func TestCreateRelease(t *testing.T) {
|
||||
|
||||
} else {
|
||||
testObejct.config.CustomURL = "http://foo"
|
||||
client, _ := github.New(&testObejct.config)
|
||||
client, _ := github.New(&testObejct.config, false)
|
||||
|
||||
err := client.CreateRelease(testObejct.releaseVersion, testObejct.generatedChangelog)
|
||||
if err != nil {
|
||||
|
||||
@@ -2,7 +2,6 @@ package gitlab
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -26,7 +25,6 @@ const GITLAB = "gitlab"
|
||||
// Client type struct
|
||||
type Client struct {
|
||||
config *config.GitLabProvider
|
||||
context context.Context
|
||||
client *http.Client
|
||||
baseURL string
|
||||
apiURL string
|
||||
@@ -36,12 +34,17 @@ type Client struct {
|
||||
}
|
||||
|
||||
// New initialize a new gitlabRelease
|
||||
func New(config *config.GitLabProvider, accessToken string) (*Client, error) {
|
||||
ctx := context.Background()
|
||||
func New(config *config.GitLabProvider, checkConfig bool) (*Client, error) {
|
||||
accessToken, err := util.GetAccessToken(fmt.Sprintf("%s_ACCESS_TOKEN", strings.ToUpper(GITLAB)))
|
||||
if err != nil && checkConfig {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tokenHeader := util.NewAddHeaderTransport(nil, "PRIVATE-TOKEN", accessToken)
|
||||
acceptHeader := util.NewAddHeaderTransport(tokenHeader, "Accept", "application/json")
|
||||
contentHeader := util.NewAddHeaderTransport(acceptHeader, "Content-Type", "application/json")
|
||||
httpClient := &http.Client{
|
||||
Transport: acceptHeader,
|
||||
Transport: contentHeader,
|
||||
Timeout: time.Second * 60,
|
||||
}
|
||||
|
||||
@@ -49,7 +52,7 @@ func New(config *config.GitLabProvider, accessToken string) (*Client, error) {
|
||||
|
||||
logger.Debugf("validate gitlab provider config")
|
||||
|
||||
if config.Repo == "" {
|
||||
if config.Repo == "" && checkConfig {
|
||||
return nil, fmt.Errorf("gitlab Repro is not set")
|
||||
}
|
||||
|
||||
@@ -65,7 +68,6 @@ func New(config *config.GitLabProvider, accessToken string) (*Client, error) {
|
||||
return &Client{
|
||||
token: accessToken,
|
||||
config: config,
|
||||
context: ctx,
|
||||
baseURL: config.CustomURL,
|
||||
apiURL: config.CustomURL + "/api/v4",
|
||||
client: httpClient,
|
||||
@@ -83,20 +85,14 @@ func (g *Client) GetCompareURL(oldVersion, newVersion string) string {
|
||||
return fmt.Sprintf("%s/%s/compare/%s...%s", g.baseURL, g.config.Repo, oldVersion, newVersion)
|
||||
}
|
||||
|
||||
//ValidateConfig for gitlab
|
||||
func (g *Client) ValidateConfig() error {
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// CreateRelease creates release on remote
|
||||
func (g *Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedChangelog *shared.GeneratedChangelog) error {
|
||||
|
||||
tag := releaseVersion.Next.Version.String()
|
||||
tag := "v" + releaseVersion.Next.Version.String()
|
||||
g.Release = tag
|
||||
g.log.Infof("create release with version %s", tag)
|
||||
url := fmt.Sprintf("%s/projects/%s/releases", g.apiURL, util.PathEscape(g.config.Repo))
|
||||
g.log.Infof("Send release to %s", url)
|
||||
g.log.Infof("Send release to %s", url)
|
||||
|
||||
bodyBytes, err := json.Marshal(Release{
|
||||
TagName: tag,
|
||||
@@ -108,6 +104,8 @@ func (g *Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedC
|
||||
return err
|
||||
}
|
||||
|
||||
g.log.Tracef("Send release config %s", bodyBytes)
|
||||
|
||||
req, err := http.NewRequest("POST", url, bytes.NewReader(bodyBytes))
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not create request: %s", err.Error())
|
||||
@@ -123,7 +121,7 @@ func (g *Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedC
|
||||
return err
|
||||
}
|
||||
|
||||
g.log.Infof("Crated release")
|
||||
g.log.Infof("Created release")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -13,54 +13,61 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
//"github.com/Nightapes/go-semantic-release/internal/releaser/util"
|
||||
"github.com/Nightapes/go-semantic-release/internal/releaser/gitlab"
|
||||
"github.com/Nightapes/go-semantic-release/internal/shared"
|
||||
"github.com/Nightapes/go-semantic-release/pkg/config"
|
||||
)
|
||||
|
||||
func TestGetCommitURL(t *testing.T) {
|
||||
|
||||
os.Setenv("GITLAB_ACCESS_TOKEN", "XXX")
|
||||
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
||||
client, err := gitlab.New(&config.GitLabProvider{
|
||||
CustomURL: "https://localhost/",
|
||||
Repo: "test/test",
|
||||
}, "aToken")
|
||||
}, true)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "https://localhost/test/test/commit/{{hash}}", client.GetCommitURL())
|
||||
}
|
||||
|
||||
func TestGetCompareURL(t *testing.T) {
|
||||
|
||||
os.Setenv("GITLAB_ACCESS_TOKEN", "XXX")
|
||||
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
||||
client, err := gitlab.New(&config.GitLabProvider{
|
||||
CustomURL: "https://localhost/",
|
||||
Repo: "test/test",
|
||||
}, "aToken")
|
||||
}, true)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "https://localhost/test/test/compare/1.0.0...1.0.1", client.GetCompareURL("1.0.0", "1.0.1"))
|
||||
}
|
||||
|
||||
func TestValidateConfig_EmptyRepro(t *testing.T) {
|
||||
os.Setenv("GITLAB_ACCESS_TOKEN", "XXX")
|
||||
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
||||
_, err := gitlab.New(&config.GitLabProvider{
|
||||
CustomURL: "https://localhost/",
|
||||
}, "aToken")
|
||||
}, true)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestValidateConfig_DefaultURL(t *testing.T) {
|
||||
os.Setenv("GITLAB_ACCESS_TOKEN", "XXX")
|
||||
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
||||
config := &config.GitLabProvider{
|
||||
Repo: "localhost/test",
|
||||
}
|
||||
_, err := gitlab.New(config, "aToken")
|
||||
_, err := gitlab.New(config, true)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "https://gitlab.com", config.CustomURL)
|
||||
}
|
||||
|
||||
func TestValidateConfig_CustomURL(t *testing.T) {
|
||||
os.Setenv("GITLAB_ACCESS_TOKEN", "XXX")
|
||||
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
||||
config := &config.GitLabProvider{
|
||||
Repo: "/localhost/test/",
|
||||
CustomURL: "https://localhost/",
|
||||
}
|
||||
_, err := gitlab.New(config, "aToken")
|
||||
_, err := gitlab.New(config, true)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "https://localhost", config.CustomURL)
|
||||
assert.Equal(t, "localhost/test", config.Repo)
|
||||
@@ -101,7 +108,7 @@ func TestCreateRelease(t *testing.T) {
|
||||
},
|
||||
responseBody: "{}",
|
||||
responseCode: 200,
|
||||
requestBody: `{"tag_name":"2.0.0","name":"title","ref":"master","description":"content","assets":{"links":null}}`,
|
||||
requestBody: `{"tag_name":"v2.0.0","name":"title","ref":"master","description":"content"}`,
|
||||
valid: true,
|
||||
},
|
||||
{
|
||||
@@ -125,7 +132,7 @@ func TestCreateRelease(t *testing.T) {
|
||||
},
|
||||
responseBody: "{}",
|
||||
responseCode: 500,
|
||||
requestBody: `{"tag_name":"2.0.0","name":"title","ref":"master","description":"content","assets":{"links":null}}`,
|
||||
requestBody: `{"tag_name":"v2.0.0","name":"title","ref":"master","description":"content"}`,
|
||||
valid: false,
|
||||
},
|
||||
{
|
||||
@@ -150,7 +157,7 @@ func TestCreateRelease(t *testing.T) {
|
||||
},
|
||||
responseCode: 400,
|
||||
responseBody: "{}",
|
||||
requestBody: `{"tag_name":"2.0.0","name":"title","ref":"master","description":"content","assets":{"links":null}}`,
|
||||
requestBody: `{"tag_name":"v2.0.0","name":"title","ref":"master","description":"content"}`,
|
||||
valid: false,
|
||||
},
|
||||
}
|
||||
@@ -181,8 +188,9 @@ func TestCreateRelease(t *testing.T) {
|
||||
if testObject.config.CustomURL == "" {
|
||||
testObject.config.CustomURL = testServer.URL
|
||||
}
|
||||
|
||||
client, err := gitlab.New(&testObject.config, "aToken")
|
||||
os.Setenv("GITLAB_ACCESS_TOKEN", "aToken")
|
||||
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
||||
client, err := gitlab.New(&testObject.config, false)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = client.CreateRelease(testObject.releaseVersion, testObject.generatedChangelog)
|
||||
@@ -307,8 +315,9 @@ func TestUploadAssets(t *testing.T) {
|
||||
if testObject.config.CustomURL == "" {
|
||||
testObject.config.CustomURL = testServer.URL
|
||||
}
|
||||
|
||||
client, err := gitlab.New(&testObject.config, "aToken")
|
||||
os.Setenv("GITLAB_ACCESS_TOKEN", "aToken")
|
||||
defer os.Unsetenv("GITLAB_ACCESS_TOKEN")
|
||||
client, err := gitlab.New(&testObject.config, false)
|
||||
assert.NoError(t, err)
|
||||
client.Release = "1.0.0"
|
||||
|
||||
|
||||
@@ -6,9 +6,6 @@ type Release struct {
|
||||
Name string `json:"name"`
|
||||
Ref string `json:"ref"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Assets struct {
|
||||
Links []*ReleaseLink `json:"links"`
|
||||
} `json:"assets"`
|
||||
}
|
||||
|
||||
// ReleaseLink struct
|
||||
|
||||
@@ -2,11 +2,11 @@ package releaser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/Nightapes/go-semantic-release/internal/gitutil"
|
||||
"github.com/Nightapes/go-semantic-release/internal/releaser/git"
|
||||
"github.com/Nightapes/go-semantic-release/internal/releaser/github"
|
||||
"github.com/Nightapes/go-semantic-release/internal/releaser/gitlab"
|
||||
"github.com/Nightapes/go-semantic-release/internal/releaser/util"
|
||||
"github.com/Nightapes/go-semantic-release/internal/shared"
|
||||
|
||||
"github.com/Nightapes/go-semantic-release/pkg/config"
|
||||
@@ -16,37 +16,37 @@ import (
|
||||
// Releasers struct type
|
||||
type Releasers struct {
|
||||
config *config.ReleaseConfig
|
||||
git *gitutil.GitUtil
|
||||
}
|
||||
|
||||
// Releaser interface for providers
|
||||
type Releaser interface {
|
||||
ValidateConfig() error
|
||||
CreateRelease(*shared.ReleaseVersion, *shared.GeneratedChangelog) error
|
||||
UploadAssets(repoDir string, assets []config.Asset) error
|
||||
GetCommitURL() string
|
||||
GetCompareURL(oldVersion, newVersion string) string
|
||||
}
|
||||
|
||||
// New initialize a Relerser
|
||||
func New(c *config.ReleaseConfig) *Releasers {
|
||||
// New initialize a releaser
|
||||
func New(c *config.ReleaseConfig, git *gitutil.GitUtil) *Releasers {
|
||||
return &Releasers{
|
||||
config: c,
|
||||
git: git,
|
||||
}
|
||||
}
|
||||
|
||||
//GetReleaser returns an initialized releaser
|
||||
func (r *Releasers) GetReleaser() (Releaser, error) {
|
||||
func (r *Releasers) GetReleaser(checkConfig bool) (Releaser, error) {
|
||||
switch r.config.Release {
|
||||
case github.GITHUB:
|
||||
log.Debugf("initialize new %s-provider", github.GITHUB)
|
||||
return github.New(&r.config.GitHubProvider)
|
||||
return github.New(&r.config.GitHubProvider, checkConfig)
|
||||
case gitlab.GITLAB:
|
||||
log.Debugf("initialize new %s-provider", gitlab.GITLAB)
|
||||
accessToken, err := util.GetAccessToken(fmt.Sprintf("%s_ACCESS_TOKEN", strings.ToUpper(gitlab.GITLAB)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return gitlab.New(&r.config.GitLabProvider, accessToken)
|
||||
return gitlab.New(&r.config.GitLabProvider, checkConfig)
|
||||
case git.GITONLY:
|
||||
log.Debugf("initialize new %s-provider", git.GITONLY)
|
||||
return git.New(&r.config.GitProvider, r.git, checkConfig)
|
||||
}
|
||||
return nil, fmt.Errorf("could not initialize a releaser from this type: %s", r.config.Release)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package config
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v2"
|
||||
@@ -10,9 +11,23 @@ import (
|
||||
|
||||
// ChangelogConfig struct
|
||||
type ChangelogConfig struct {
|
||||
PrintAll bool `yaml:"printAll,omitempty"`
|
||||
Template string `yaml:"template,omitempty"`
|
||||
TemplatePath string `yaml:"templatePath,omitempty"`
|
||||
PrintAll bool `yaml:"printAll,omitempty"`
|
||||
TemplateTitle string `yaml:"title,omitempty"`
|
||||
TemplatePath string `yaml:"templatePath,omitempty"`
|
||||
Docker ChangelogDocker `yaml:"docker,omitempty"`
|
||||
NPM ChangelogNPM `yaml:"npm,omitempty"`
|
||||
}
|
||||
|
||||
//ChangelogDocker type struct
|
||||
type ChangelogDocker struct {
|
||||
Latest bool `yaml:"latest"`
|
||||
Repository string `yaml:"repository"`
|
||||
}
|
||||
|
||||
//ChangelogNPM type struct
|
||||
type ChangelogNPM struct {
|
||||
YARN bool `yaml:"latest"`
|
||||
Repository string `yaml:"repository"`
|
||||
}
|
||||
|
||||
//Asset type struct
|
||||
@@ -36,6 +51,20 @@ type GitLabProvider struct {
|
||||
AccessToken string
|
||||
}
|
||||
|
||||
// GitProvider struct
|
||||
type GitProvider struct {
|
||||
Email string `yaml:"email"`
|
||||
Username string `yaml:"user"`
|
||||
Auth string `yaml:"auth"`
|
||||
SSH bool `yaml:"ssh"`
|
||||
}
|
||||
|
||||
// Hooks struct
|
||||
type Hooks struct {
|
||||
PreRelease []string `yaml:"preRelease"`
|
||||
PostRelease []string `yaml:"postRelease"`
|
||||
}
|
||||
|
||||
// ReleaseConfig struct
|
||||
type ReleaseConfig struct {
|
||||
CommitFormat string `yaml:"commitFormat"`
|
||||
@@ -44,7 +73,9 @@ type ReleaseConfig struct {
|
||||
Release string `yaml:"release,omitempty"`
|
||||
GitHubProvider GitHubProvider `yaml:"github,omitempty"`
|
||||
GitLabProvider GitLabProvider `yaml:"gitlab,omitempty"`
|
||||
GitProvider GitProvider `yaml:"git,omitempty"`
|
||||
Assets []Asset `yaml:"assets"`
|
||||
Hooks Hooks `yaml:"hooks"`
|
||||
ReleaseTitle string `yaml:"title"`
|
||||
IsPreRelease bool
|
||||
}
|
||||
@@ -57,13 +88,31 @@ func Read(configPath string) (*ReleaseConfig, error) {
|
||||
return &ReleaseConfig{}, err
|
||||
}
|
||||
|
||||
var releaseConfig ReleaseConfig
|
||||
err = yaml.Unmarshal(content, &releaseConfig)
|
||||
log.Tracef("Found config %s", string(content))
|
||||
releaseConfig := &ReleaseConfig{}
|
||||
err = yaml.Unmarshal(content, releaseConfig)
|
||||
if err != nil {
|
||||
return &ReleaseConfig{}, err
|
||||
}
|
||||
|
||||
log.Tracef("Found config %+v", releaseConfig)
|
||||
org := *releaseConfig
|
||||
|
||||
return &releaseConfig, nil
|
||||
releaseConfig.Hooks = Hooks{}
|
||||
|
||||
configWithoutHooks, err := yaml.Marshal(releaseConfig)
|
||||
if err != nil {
|
||||
return &ReleaseConfig{}, err
|
||||
}
|
||||
configWithoutHooks = []byte(os.ExpandEnv(string(configWithoutHooks)))
|
||||
releaseConfigWithExpanedEnvs := &ReleaseConfig{}
|
||||
err = yaml.Unmarshal(configWithoutHooks, releaseConfigWithExpanedEnvs)
|
||||
if err != nil {
|
||||
return &ReleaseConfig{}, err
|
||||
}
|
||||
|
||||
releaseConfigWithExpanedEnvs.Hooks = org.Hooks
|
||||
|
||||
log.Tracef("Found config %+v", releaseConfigWithExpanedEnvs)
|
||||
|
||||
return releaseConfigWithExpanedEnvs, nil
|
||||
}
|
||||
|
||||
@@ -41,6 +41,9 @@ func TestWriteAndReadCache(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
os.Setenv("TEST_CONFIG", "value")
|
||||
defer os.Unsetenv("TEST_CONFIG")
|
||||
|
||||
completePath := path.Join(path.Dir(dir), ".release.yml")
|
||||
content := []byte(`
|
||||
commitFormat: angular
|
||||
@@ -53,9 +56,12 @@ branch:
|
||||
add_git_releases: alpha
|
||||
changelog:
|
||||
printAll: false
|
||||
template: ''
|
||||
templatePath: ''
|
||||
template: ""
|
||||
templatePath: '${TEST_CONFIG}'
|
||||
release: 'github'
|
||||
hooks:
|
||||
preRelease:
|
||||
- "Test hook ${RELEASE_VERSION}"
|
||||
assets:
|
||||
- name: ./build/go-semantic-release
|
||||
compress: false
|
||||
@@ -74,15 +80,20 @@ github:
|
||||
CommitFormat: "angular",
|
||||
Branch: map[string]string{"add_git_releases": "alpha", "alpha": "alpha", "beta": "beta", "master": "release", "rc": "rc"},
|
||||
Changelog: config.ChangelogConfig{
|
||||
PrintAll: false,
|
||||
Template: "",
|
||||
TemplatePath: ""},
|
||||
PrintAll: false,
|
||||
TemplateTitle: "",
|
||||
TemplatePath: "value"},
|
||||
Release: "github",
|
||||
GitHubProvider: config.GitHubProvider{
|
||||
Repo: "go-semantic-release",
|
||||
User: "nightapes",
|
||||
CustomURL: "",
|
||||
AccessToken: ""},
|
||||
Hooks: config.Hooks{
|
||||
PreRelease: []string{
|
||||
"Test hook ${RELEASE_VERSION}",
|
||||
},
|
||||
},
|
||||
Assets: []config.Asset{
|
||||
config.Asset{
|
||||
Name: "./build/go-semantic-release",
|
||||
@@ -92,20 +103,3 @@ github:
|
||||
}, result)
|
||||
|
||||
}
|
||||
|
||||
// func TestWriteNotFound(t *testing.T) {
|
||||
|
||||
// err := cache.Write("notfound/dir", shared.ReleaseVersion{
|
||||
// Last: shared.ReleaseVersionEntry{
|
||||
// Commit: "12345",
|
||||
// Version: createVersion("1.0.0"),
|
||||
// },
|
||||
// Next: shared.ReleaseVersionEntry{
|
||||
// Commit: "12346",
|
||||
// Version: createVersion("1.1.0"),
|
||||
// },
|
||||
// Branch: "master",
|
||||
// })
|
||||
// assert.Errorf(t, err, "Write non exsiting file")
|
||||
|
||||
// }
|
||||
|
||||
@@ -2,7 +2,6 @@ package semanticrelease
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
@@ -12,6 +11,7 @@ import (
|
||||
"github.com/Nightapes/go-semantic-release/internal/changelog"
|
||||
"github.com/Nightapes/go-semantic-release/internal/ci"
|
||||
"github.com/Nightapes/go-semantic-release/internal/gitutil"
|
||||
"github.com/Nightapes/go-semantic-release/internal/hooks"
|
||||
"github.com/Nightapes/go-semantic-release/internal/releaser"
|
||||
"github.com/Nightapes/go-semantic-release/internal/releaser/util"
|
||||
"github.com/Nightapes/go-semantic-release/internal/shared"
|
||||
@@ -21,16 +21,17 @@ import (
|
||||
|
||||
// SemanticRelease struct
|
||||
type SemanticRelease struct {
|
||||
config *config.ReleaseConfig
|
||||
gitutil *gitutil.GitUtil
|
||||
analyzer *analyzer.Analyzer
|
||||
calculator *calculator.Calculator
|
||||
releaser releaser.Releaser
|
||||
repository string
|
||||
config *config.ReleaseConfig
|
||||
gitutil *gitutil.GitUtil
|
||||
analyzer *analyzer.Analyzer
|
||||
calculator *calculator.Calculator
|
||||
releaser releaser.Releaser
|
||||
repository string
|
||||
checkConfig bool
|
||||
}
|
||||
|
||||
// New SemanticRelease struct
|
||||
func New(c *config.ReleaseConfig, repository string) (*SemanticRelease, error) {
|
||||
func New(c *config.ReleaseConfig, repository string, checkConfig bool) (*SemanticRelease, error) {
|
||||
util, err := gitutil.New(repository)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -41,24 +42,29 @@ func New(c *config.ReleaseConfig, repository string) (*SemanticRelease, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
releaser, err := releaser.New(c).GetReleaser()
|
||||
if !checkConfig {
|
||||
log.Infof("Ignore config checks!. No guarantee to run without issues")
|
||||
}
|
||||
|
||||
releaser, err := releaser.New(c, util).GetReleaser(checkConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &SemanticRelease{
|
||||
config: c,
|
||||
gitutil: util,
|
||||
releaser: releaser,
|
||||
analyzer: analyzer,
|
||||
repository: repository,
|
||||
calculator: calculator.New(),
|
||||
config: c,
|
||||
gitutil: util,
|
||||
releaser: releaser,
|
||||
analyzer: analyzer,
|
||||
repository: repository,
|
||||
checkConfig: checkConfig,
|
||||
calculator: calculator.New(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
//GetCIProvider result with ci config
|
||||
func (s *SemanticRelease) GetCIProvider() (*ci.ProviderConfig, error) {
|
||||
return ci.GetCIProvider(s.gitutil, ci.ReadAllEnvs())
|
||||
return ci.GetCIProvider(s.gitutil, s.checkConfig, ci.ReadAllEnvs())
|
||||
}
|
||||
|
||||
// GetNextVersion from .version or calculate new from commits
|
||||
@@ -98,14 +104,21 @@ func (s *SemanticRelease) GetNextVersion(provider *ci.ProviderConfig, force bool
|
||||
analyzedCommits := s.analyzer.Analyze(commits)
|
||||
|
||||
var newVersion semver.Version
|
||||
foundBranchConfig := false
|
||||
for branch, releaseType := range s.config.Branch {
|
||||
if provider.Branch == branch || strings.HasPrefix(provider.Branch, branch) {
|
||||
if provider.Branch == branch {
|
||||
log.Debugf("Found branch config for branch %s with release type %s", provider.Branch, releaseType)
|
||||
newVersion = s.calculator.CalculateNewVersion(analyzedCommits, lastVersion, releaseType, firstRelease)
|
||||
foundBranchConfig = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !foundBranchConfig {
|
||||
log.Warnf("No branch config found for branch %s, will return last known version", provider.Branch)
|
||||
newVersion = *lastVersion
|
||||
}
|
||||
|
||||
releaseVersion := shared.ReleaseVersion{
|
||||
Next: shared.ReleaseVersionEntry{
|
||||
Commit: provider.Commit,
|
||||
@@ -177,7 +190,7 @@ func (s *SemanticRelease) WriteChangeLog(changelogContent, file string) error {
|
||||
return ioutil.WriteFile(file, []byte(changelogContent), 0644)
|
||||
}
|
||||
|
||||
// Release pusblish release to provider
|
||||
// Release publish release to provider
|
||||
func (s *SemanticRelease) Release(provider *ci.ProviderConfig, force bool) error {
|
||||
|
||||
if provider.IsPR {
|
||||
@@ -201,27 +214,31 @@ func (s *SemanticRelease) Release(provider *ci.ProviderConfig, force bool) error
|
||||
return nil
|
||||
}
|
||||
|
||||
generatedChanglog, err := s.GetChangelog(releaseVersion)
|
||||
hook := hooks.New(s.config, releaseVersion)
|
||||
|
||||
generatedChangelog, err := s.GetChangelog(releaseVersion)
|
||||
if err != nil {
|
||||
log.Debugf("Could not get changelog")
|
||||
return err
|
||||
}
|
||||
|
||||
releaser, err := releaser.New(s.config).GetReleaser()
|
||||
err = hook.PreRelease()
|
||||
if err != nil {
|
||||
log.Debugf("Error during pre release hook")
|
||||
return err
|
||||
}
|
||||
|
||||
err = releaser.ValidateConfig()
|
||||
if err = s.releaser.CreateRelease(releaseVersion, generatedChangelog); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = s.releaser.UploadAssets(s.repository, s.config.Assets); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = hook.PostRelease()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = releaser.CreateRelease(releaseVersion, generatedChanglog); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = releaser.UploadAssets(s.repository, s.config.Assets); err != nil {
|
||||
log.Debugf("Error during post release hook")
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user