Skip to content

Commit

Permalink
[OP-1796] Deferred PR creation (#19)
Browse files Browse the repository at this point in the history
* feat: Added HTML templating

* feat: Added static files

* feat: Added package browsing

* feat: Added 'Create PR' page

* feat: Use query params

* feat: Added POST endpoint for performing PR creation

* tmp: Disabling dry run

* feat: Added general 404 page

* feat: Added general 405 page

* feat: Create and show PR diffs

* chore: Use existing funcs

* go mod tidy

* feat: Added JavaScript that adds 'Loading please wait' text

* feat: Added more info to dry-run jobs

* Fixed default description template

* feat: Fixed post form data processing

* bugfix: Properly propagate diff

* chore: Updated papercss

* feat: Added Gin logger shim

* feat: Added HTML for creating comment

* feat: Added JS to persist query params

* chore: Removed excess logging

* Rephrasing

* Changed Gin logger to use 'caller' special field name

* Border styling

* chore: PR create in separate Go file

* chore: Some refactoring, and mark Jira issue as required

* chore: Refactored more, removing 'jiraCreateComment' bool

* feat: Added code path for linking to deferred PR creation

* Updated log message

* Fixed URI param parsing

* bugfix: Fixed JS glitch

* chore: Removed excess TryFindNormalized

* chore: Added test for censoring URL, and fixed a bug

* chore: Removed unused function

* chore: Smallfixes to HTML

* chore: Linting fixes

* docs: Explained new configs in default config

* Update pkg/server/prcreate.go

* Added newline to schema at EOF

* Added some godoc
  • Loading branch information
applejag authored Jul 19, 2023
1 parent 07153c0 commit 758c39d
Show file tree
Hide file tree
Showing 55 changed files with 1,939 additions and 98 deletions.
14 changes: 13 additions & 1 deletion cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import (
"gopkg.in/yaml.v3"
)

var configFlags = struct {
noRedacting bool
}{}

// configCmd represents the config command
var configCmd = &cobra.Command{
Use: "config",
Expand All @@ -32,10 +36,18 @@ var configCmd = &cobra.Command{
enc := yaml.NewEncoder(os.Stdout)
enc.SetIndent(2)
defer enc.Close()
return enc.Encode(cfg)

printableCfg := cfg
if !configFlags.noRedacting {
printableCfg = printableCfg.Censored()
}

return enc.Encode(printableCfg)
},
}

func init() {
rootCmd.AddCommand(configCmd)

configCmd.Flags().BoolVar(&configFlags.noRedacting, "no-redacting", false, "Show secret fields, instead of redacting tokens and private keys.")
}
19 changes: 18 additions & 1 deletion cmd/config_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ var configSchemaCmd = &cobra.Command{
fmt.Println(string(data))
return nil
}
if err := os.WriteFile(configSchemaFlags.output, data, 0644); err != nil {
if writeFile(configSchemaFlags.output, data); err != nil {
return err
}
log.Info().
Expand All @@ -63,6 +63,23 @@ var configSchemaCmd = &cobra.Command{
},
}

func writeFile(fileName string, data []byte) error {
file, err := os.OpenFile(configSchemaFlags.output, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
return err
}
defer file.Close()
_, err = file.Write(data)
if err != nil {
return err
}
_, err = file.Write([]byte("\n"))
if err != nil {
return err
}
return file.Close()
}

func marshalJSON(v any, indented bool) ([]byte, error) {
if indented {
return json.MarshalIndent(v, "", " ")
Expand Down
10 changes: 7 additions & 3 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package cmd

import (
"io/fs"
"os"
"path/filepath"
"runtime/debug"
Expand All @@ -33,7 +34,9 @@ import (
)

var (
cfg config.Config
cfg config.Config
htmlTemplates fs.FS
htmlStaticFiles fs.FS

appVersion string // may be set via `go build` flags
goVersion string
Expand All @@ -55,7 +58,9 @@ var rootCmd = &cobra.Command{
},
}

func Execute(defaultConfig config.Config) {
func Execute(defaultConfig config.Config, templatesFS fs.FS, staticFilesFS fs.FS) {
htmlTemplates = templatesFS
htmlStaticFiles = staticFilesFS
cfg = defaultConfig

// Add flag definitons here that need to be binded with configs
Expand Down Expand Up @@ -88,7 +93,6 @@ func init() {
appVersion = buildInfo.Main.Version
}
goVersion = strings.TrimPrefix(buildInfo.GoVersion, "go")
} else {
}
if appVersion == "" {
appVersion = "unknown"
Expand Down
6 changes: 5 additions & 1 deletion cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ func init() {
}

func run() error {
if htmlTemplates == nil {
return fmt.Errorf("no HTML templates loaded")
}

jiraClient, err := jira.New(&cfg.Jira)
if err != nil {
return fmt.Errorf("create jira client: %w", err)
Expand All @@ -69,7 +73,7 @@ func run() error {
return err
}

s := server.New(&cfg, jiraClient, patcher)
s := server.New(&cfg, jiraClient, patcher, htmlTemplates, htmlStaticFiles)
return s.Serve()
}

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/andygrunwald/go-jira v1.15.1
github.com/bradleyfalzon/ghinstallation/v2 v2.1.1-0.20221216144751-8f41e6541ca6
github.com/fatih/color v1.13.0
github.com/gin-contrib/multitemplate v0.0.0-20230212012517-45920c92c271
github.com/gin-gonic/gin v1.8.1
github.com/golang-jwt/jwt/v4 v4.4.3
github.com/google/go-github/v48 v48.2.0
Expand Down
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/gin-contrib/multitemplate v0.0.0-20230212012517-45920c92c271 h1:s+boMV47gwTyff2PL+k6V33edJpp+K5y3QPzZlRhno8=
github.com/gin-contrib/multitemplate v0.0.0-20230212012517-45920c92c271/go.mod h1:XLLtIXoP9+9zGcEDc7gAGV3AksGPO+vzv4kXHMJSdU0=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
Expand All @@ -82,8 +84,10 @@ github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
Expand Down Expand Up @@ -205,6 +209,7 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
Expand Down Expand Up @@ -271,6 +276,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
Expand Down Expand Up @@ -566,6 +572,7 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
27 changes: 26 additions & 1 deletion jelease.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@
"properties": {
"port": {
"type": "integer"
},
"publicUrl": {
"$ref": "#/$defs/url"
}
},
"additionalProperties": false,
Expand Down Expand Up @@ -255,6 +258,9 @@
"projectNameCustomField": {
"type": "integer"
},
"prDeferredCreation": {
"type": "boolean"
},
"comments": {
"$ref": "#/$defs/jiraIssueComments"
}
Expand All @@ -278,6 +284,9 @@
},
"prFailed": {
"$ref": "#/$defs/template"
},
"prDeferredCreation": {
"$ref": "#/$defs/template"
}
},
"additionalProperties": false,
Expand Down Expand Up @@ -503,6 +512,22 @@
"template": {
"type": "string",
"title": "Go template"
},
"url": {
"oneOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"format": "uri",
"title": "URL",
"examples": [
"http://localhost:8080",
"https://example.com"
]
}
}
}
}
24 changes: 22 additions & 2 deletions jelease.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ github:
{{ with .JiraIssue }}[{{ . }}] {{ end -}}
Update `{{ .Package }}` to {{ .Version }}
description: |
{{ with .JiraIssue }}
{{ with .JiraIssue -}}
Jira issue: {{ . }}
{{ end }}
{{ end -}}
Changed version of `{{ .Package }}` to {{ .Version }}
<sub>
Expand Down Expand Up @@ -145,6 +145,11 @@ jira:
project: ''
projectNameCustomField: 1084

# prDeferredCreation means Jelease will send a link to where user can
# manually trigger the PR creation, instead of creating it automatically.
# Note that http.publicUrl also has to be set for this.
prDeferredCreation: false

comments:
updatedIssue: |-
(i) This Jira issue was updated to *{{ .Version }}*.
Expand All @@ -163,6 +168,9 @@ jira:
{{ .Error }}
{code}
prDeferredCreation: |-
Can create pull request for updating *{{ .Package }}* to *{{ .Version }}*: [Click to create|{{ .URL }}]
noConfig: >-
{color:#505F79}(i) _No config found for package *{{ .Package }}*.
You can add some to automatically create PRs with the update._{color}
Expand All @@ -187,6 +195,18 @@ newReleases:
http:
port: 8080

# URL to reach Jelease. Used when Jelease needs to link back to itself
# in Jira comments. Trailing slash is optional. Example:
# publicUrl: http://locahost:8080
# will resolve links such as:
# http://locahost:8080/packages/my-package/create-pr
#
# Base paths will be honored, such as:
# publicUrl: http://my-infra.example.com/jelease/
# will resolve links such as:
# http://my-infra.example.com/jelease/packages/my-package/create-pr
publicUrl: null

# Console logging settings.
log:
format: pretty # pretty | json
Expand Down
22 changes: 19 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,38 @@
package main

import (
"embed"
"fmt"
"io/fs"

"github.com/RiskIdent/jelease/cmd"
"github.com/RiskIdent/jelease/pkg/config"
"gopkg.in/yaml.v3"

_ "embed"
)

//go:embed jelease.yaml
var defaultConfigYAML []byte

//go:embed templates
var templatesFS embed.FS

//go:embed static
var staticFilesFS embed.FS

func main() {
var defaultConfig config.Config
if err := yaml.Unmarshal(defaultConfigYAML, &defaultConfig); err != nil {
panic(fmt.Errorf("Parse embedded config: %w", err))
}
cmd.Execute(defaultConfig)
templatesFSSub := mustSub(templatesFS, "templates")
staticFilesFSSub := mustSub(staticFilesFS, "static")
cmd.Execute(defaultConfig, templatesFSSub, staticFilesFSSub)
}

func mustSub(fsys fs.FS, dir string) fs.FS {
sub, err := fs.Sub(fsys, dir)
if err != nil {
panic(fmt.Errorf("Get subdirectory of filesystem: %w", err))
}
return sub
}
Loading

0 comments on commit 758c39d

Please sign in to comment.