From 742457ad42b45b175e98c504f0ad4ece16c90ed9 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Mon, 7 Aug 2023 15:14:24 +0200 Subject: [PATCH 01/74] feat: with initial cmd and server Signed-off-by: kjuulh --- cmd/contractor/main.go | 179 +++++++++++++++++++++++++++++++++++++++++ go.mod | 34 ++++++++ go.sum | 86 ++++++++++++++++++++ main.go | 13 +++ 4 files changed, 312 insertions(+) create mode 100644 cmd/contractor/main.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go diff --git a/cmd/contractor/main.go b/cmd/contractor/main.go new file mode 100644 index 0000000..6e559ee --- /dev/null +++ b/cmd/contractor/main.go @@ -0,0 +1,179 @@ +package contractor + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "strings" + + "github.com/gin-gonic/gin" + "github.com/spf13/cobra" +) + +type createHook struct { + Active bool `json:"active"` + AuthorizationHeader string `json:"authorization_header"` + BranchFilter string `json:"branch_filter"` + Config map[string]string `json:"config"` + Events []string `json:"events"` + Type string `json:"type"` +} + +func installCmd() *cobra.Command { + var ( + owner string + repository string + serverType string + + url string + token string + ) + + cmd := &cobra.Command{ + Use: "install", + + Run: func(cmd *cobra.Command, args []string) { + client := http.DefaultClient + createHookOptions := createHook{ + Active: true, + AuthorizationHeader: "", + BranchFilter: "*", + Config: map[string]string{ + "url": "http://10.0.9.1:8080/gitea/webhook", + "content_type": "json", + }, + Events: []string{ + "pull_request_comment", + }, + Type: "gitea", + } + + body, err := json.Marshal(createHookOptions) + if err != nil { + log.Println("failed to marshal request body: %w", err) + return + } + bodyReader := bytes.NewReader(body) + + request, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/repos/%s/%s/hooks", strings.TrimSuffix(url, "/"), owner, repository), bodyReader) + if err != nil { + log.Println("failed to form create hook request: %s", err.Error()) + return + } + request.Header.Add("Authorization", fmt.Sprintf("token %s", token)) + request.Header.Add("Content-Type", "application/json") + + resp, err := client.Do(request) + if err != nil { + log.Printf("failed to register hook: %s", err.Error()) + return + } + + if resp.StatusCode > 299 { + log.Printf("failed to register with status code: %d", resp.StatusCode) + respBody, err := io.ReadAll(resp.Body) + if err != nil { + log.Printf("failed to read body of error response: %s", err.Error()) + } else { + log.Printf("request body: %s", string(respBody)) + } + } + }, + } + + cmd.Flags().StringVarP(&owner, "owner", "o", "", "the owner for which the repository belongs") + cmd.Flags().StringVarP(&repository, "repository", "p", "", "the repository to install") + cmd.Flags().StringVar(&serverType, "server-type", "gitea", "the server type to use [gitea, github]") + cmd.MarkFlagRequired("owner") + cmd.MarkFlagRequired("repository") + + cmd.PersistentFlags().StringVar(&url, "url", "", "the api url of the server") + cmd.PersistentFlags().StringVar(&token, "token", "", "the token to authenticate with") + + return cmd +} + +func serverCmd() *cobra.Command { + var ( + url string + token string + ) + + cmd := &cobra.Command{ + Use: "server", + } + + cmd.PersistentFlags().StringVar(&url, "url", "", "the api url of the server") + cmd.PersistentFlags().StringVar(&token, "token", "", "the token to authenticate with") + + cmd.AddCommand(serverServeCmd()) + + return cmd +} + +func serverServeCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "serve", + Run: func(cmd *cobra.Command, args []string) { + engine := gin.Default() + + gitea := engine.Group("/gitea") + { + gitea.POST("/webhook", func(ctx *gin.Context) { + log.Println("received") + + type GiteaWebhookRequest struct { + Action string `json:"action"` + Issue struct { + Id int `json:"id"` + Number int `json:"number"` + } `json:"issue"` + Comment struct { + Body string `json:"body"` + } `json:"comment"` + Repository struct { + FullName string `json:"full_name"` + } + } + + var request GiteaWebhookRequest + + if err := ctx.BindJSON(&request); err != nil { + ctx.AbortWithError(500, err) + return + } + + command, ok := validateBotComment(request.Comment.Body) + if ok { + log.Printf("got webhook request: contractor %s", command) + } + + ctx.Status(204) + }) + } + + engine.Run("0.0.0.0:8080") + }, + } + + return cmd +} + +func validateBotComment(s string) (request string, ok bool) { + if after, ok := strings.CutPrefix(s, "/contractor"); ok { + return strings.TrimSpace(after), true + } + + return "", false +} + +func RootCmd() *cobra.Command { + cmd := &cobra.Command{Use: "contractor"} + + cmd.AddCommand(installCmd(), serverCmd()) + + return cmd +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..ddde2ba --- /dev/null +++ b/go.mod @@ -0,0 +1,34 @@ +module git.front.kjuulh.io/kjuulh/contractor + +go 1.20 + +require ( + github.com/bytedance/sonic v1.9.1 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gin-gonic/gin v1.9.1 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.14.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/leodido/go-urn v1.2.4 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/spf13/cobra v1.7.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.11 // indirect + golang.org/x/arch v0.3.0 // indirect + golang.org/x/crypto v0.9.0 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..8b0e31f --- /dev/null +++ b/go.sum @@ -0,0 +1,86 @@ +github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= +github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= +github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +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.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= +github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= +github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= +github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= +github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= +golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/main.go b/main.go new file mode 100644 index 0000000..efd59d9 --- /dev/null +++ b/main.go @@ -0,0 +1,13 @@ +package main + +import ( + "log" + + "git.front.kjuulh.io/kjuulh/contractor/cmd/contractor" +) + +func main() { + if err := contractor.RootCmd().Execute(); err != nil { + log.Fatal(err) + } +} -- 2.45.2 From 81308eeb939890c6c2f1e4b8f6dcc13bb419de43 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Tue, 8 Aug 2023 14:15:19 +0200 Subject: [PATCH 02/74] feat: with main loop Signed-off-by: kjuulh --- .gitignore | 1 + cmd/contractor/main.go | 669 ++++++++++++++++++++++++++++++++++++++--- go.mod | 26 +- go.sum | 63 +++- main.go | 6 + 5 files changed, 702 insertions(+), 63 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env diff --git a/cmd/contractor/main.go b/cmd/contractor/main.go index 6e559ee..5ad8051 100644 --- a/cmd/contractor/main.go +++ b/cmd/contractor/main.go @@ -2,14 +2,22 @@ package contractor import ( "bytes" + "context" "encoding/json" + "errors" "fmt" + "html" "io" "log" "net/http" + "os" "strings" + "sync" + "time" + "dagger.io/dagger" "github.com/gin-gonic/gin" + "github.com/google/uuid" "github.com/spf13/cobra" ) @@ -36,57 +44,16 @@ func installCmd() *cobra.Command { Use: "install", Run: func(cmd *cobra.Command, args []string) { - client := http.DefaultClient - createHookOptions := createHook{ - Active: true, - AuthorizationHeader: "", - BranchFilter: "*", - Config: map[string]string{ - "url": "http://10.0.9.1:8080/gitea/webhook", - "content_type": "json", - }, - Events: []string{ - "pull_request_comment", - }, - Type: "gitea", - } - - body, err := json.Marshal(createHookOptions) - if err != nil { - log.Println("failed to marshal request body: %w", err) - return - } - bodyReader := bytes.NewReader(body) - - request, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/repos/%s/%s/hooks", strings.TrimSuffix(url, "/"), owner, repository), bodyReader) - if err != nil { - log.Println("failed to form create hook request: %s", err.Error()) - return - } - request.Header.Add("Authorization", fmt.Sprintf("token %s", token)) - request.Header.Add("Content-Type", "application/json") - - resp, err := client.Do(request) - if err != nil { - log.Printf("failed to register hook: %s", err.Error()) - return - } - - if resp.StatusCode > 299 { - log.Printf("failed to register with status code: %d", resp.StatusCode) - respBody, err := io.ReadAll(resp.Body) - if err != nil { - log.Printf("failed to read body of error response: %s", err.Error()) - } else { - log.Printf("request body: %s", string(respBody)) - } + if err := NewGiteaClient(&url, &token).CreateWebhook(owner, repository); err != nil { + log.Printf("failed to add create webhook: %s", err.Error()) } }, } cmd.Flags().StringVarP(&owner, "owner", "o", "", "the owner for which the repository belongs") cmd.Flags().StringVarP(&repository, "repository", "p", "", "the repository to install") - cmd.Flags().StringVar(&serverType, "server-type", "gitea", "the server type to use [gitea, github]") + cmd.Flags(). + StringVar(&serverType, "server-type", "gitea", "the server type to use [gitea, github]") cmd.MarkFlagRequired("owner") cmd.MarkFlagRequired("repository") @@ -102,6 +69,78 @@ func serverCmd() *cobra.Command { token string ) + giteaClient := NewGiteaClient(&url, &token) + renovateClient := NewRenovateClient("") + queue := NewGoQueue() + queue.Subscribe( + MessageTypeRefreshRepository, + func(ctx context.Context, item *QueueMessage) error { + log.Printf("handling message: %s, content: %s", item.Type, item.Content) + return nil + }, + ) + queue.Subscribe( + MessageTypeRefreshRepositoryDone, + func(ctx context.Context, item *QueueMessage) error { + log.Printf("handling message: %s, content: %s", item.Type, item.Content) + return nil + }, + ) + queue.Subscribe( + MessageTypeRefreshRepository, + func(ctx context.Context, item *QueueMessage) error { + var request RefreshRepositoryRequest + if err := json.Unmarshal([]byte(item.Content), &request); err != nil { + log.Printf("failed to unmarshal request body: %s", err.Error()) + return err + } + + cancelCtx, cancel := context.WithTimeout(ctx, time.Second*30) + defer cancel() + + if err := renovateClient.RefreshRepository(cancelCtx, request.Owner, request.Repository); err != nil { + queue.Insert(MessageTypeRefreshRepositoryDone, RefreshDoneRepositoryRequest{ + Repository: request.Repository, + Owner: request.Owner, + PullRequestID: request.PullRequestID, + CommentID: request.CommentID, + CommentBody: request.CommentBody, + ReportProgress: request.ReportProgress, + Status: "failed", + Error: err.Error(), + }) + + return err + } + + queue.Insert(MessageTypeRefreshRepositoryDone, RefreshDoneRepositoryRequest{ + Repository: request.Repository, + Owner: request.Owner, + PullRequestID: request.PullRequestID, + CommentID: request.CommentID, + CommentBody: request.CommentBody, + ReportProgress: request.ReportProgress, + Status: "done", + Error: "", + }) + + return nil + }, + ) + + queue.Subscribe( + MessageTypeRefreshRepositoryDone, + func(ctx context.Context, item *QueueMessage) error { + var doneRequest RefreshDoneRepositoryRequest + if err := json.Unmarshal([]byte(item.Content), &doneRequest); err != nil { + log.Printf("failed to unmarshal request body: %s", err.Error()) + return err + } + + return giteaClient.EditComment(ctx, &doneRequest) + }, + ) + cmd := &cobra.Command{ Use: "server", } @@ -109,12 +148,42 @@ func serverCmd() *cobra.Command { cmd.PersistentFlags().StringVar(&url, "url", "", "the api url of the server") cmd.PersistentFlags().StringVar(&token, "token", "", "the token to authenticate with") - cmd.AddCommand(serverServeCmd()) + cmd.AddCommand(serverServeCmd(&url, &token, queue, giteaClient)) return cmd } -func serverServeCmd() *cobra.Command { +const ( + MessageTypeRefreshRepository = "refresh_repository" + MessageTypeRefreshRepositoryDone = "refresh_repository_done" +) + +type RefreshRepositoryRequest struct { + Repository string `json:"repository"` + Owner string `json:"owner"` + PullRequestID int `json:"pullRequestId"` + CommentID int `json:"commentId"` + CommentBody string `json:"commentBody"` + ReportProgress bool `json:"reportProgress"` +} + +type RefreshDoneRepositoryRequest struct { + Repository string `json:"repository"` + Owner string `json:"owner"` + PullRequestID int `json:"pullRequestId"` + CommentID int `json:"commentId"` + CommentBody string `json:"commentBody"` + ReportProgress bool `json:"reportProgress"` + Status string `json:"status"` + Error string `json:"error"` +} + +func serverServeCmd( + url *string, + token *string, + queue *GoQueue, + giteaClient *GiteaClient, +) *cobra.Command { cmd := &cobra.Command{ Use: "serve", Run: func(cmd *cobra.Command, args []string) { @@ -149,9 +218,41 @@ func serverServeCmd() *cobra.Command { command, ok := validateBotComment(request.Comment.Body) if ok { log.Printf("got webhook request: contractor %s", command) - } - ctx.Status(204) + bot := NewBotHandler(giteaClient) + output, err := bot.Handle(command) + if err != nil { + log.Printf("failed to run bot handler with error: %s", err.Error()) + } + + parts := strings.Split(request.Repository.FullName, "/") + + comment, err := bot.AppendComment( + parts[0], + parts[1], + request.Issue.Number, + output, + ) + if err != nil { + ctx.AbortWithError(500, err) + return + } + + if err := queue.Insert(MessageTypeRefreshRepository, RefreshRepositoryRequest{ + Repository: parts[1], + Owner: parts[0], + PullRequestID: request.Issue.Number, + CommentID: comment.ID, + CommentBody: comment.Body, + ReportProgress: true, + }); err != nil { + ctx.AbortWithError(500, err) + return + } + + ctx.Status(204) + + } }) } @@ -177,3 +278,473 @@ func RootCmd() *cobra.Command { return cmd } + +type BotHandler struct { + giteaClient *GiteaClient +} + +func NewBotHandler(gitea *GiteaClient) *BotHandler { + return &BotHandler{giteaClient: gitea} +} + +func (b *BotHandler) Handle(input string) (output string, err error) { + innerHandle := func(input string) (output string, err error) { + if strings.HasPrefix(input, "help") { + return b.Help(), nil + } + + if strings.HasPrefix(input, "refresh") { + return ` +

Contractor triggered renovate refresh on this repository

+This comment will be updated with status + + + +`, nil + } + + return b.Help(), errors.New("could not recognize command") + } + + output, err = innerHandle(input) + output = fmt.Sprintf( + "%s\nThis comment was generated by Contractor", + output, + ) + return output, err +} + +func (b *BotHandler) Help() string { + return `
+

/contractor [command]

+ +Commands: + +* /contractor help + * triggers the help menu +* /contractor refresh + * triggers renovate to refresh the current pull request +
` +} + +type AddCommentResponse struct { + Body string `json:"body"` + ID int `json:"id"` +} + +func (b *BotHandler) AppendComment( + owner string, + repository string, + pullRequest int, + comment string, +) (*AddCommentResponse, error) { + return b.giteaClient.AddComment(owner, repository, pullRequest, comment) +} + +type QueueMessage struct { + Type string `json:"type"` + Content string `json:"content"` +} + +type GoQueue struct { + queue []*QueueMessage + queueLock sync.Mutex + subscribers map[string]map[string]func(ctx context.Context, item *QueueMessage) error + subscribersLock sync.RWMutex +} + +func NewGoQueue() *GoQueue { + return &GoQueue{ + queue: make([]*QueueMessage, 0), + subscribers: make( + map[string]map[string]func(ctx context.Context, item *QueueMessage) error, + ), + } +} + +func (gq *GoQueue) Subscribe( + messageType string, + callback func(ctx context.Context, item *QueueMessage) error, +) string { + gq.subscribersLock.Lock() + defer gq.subscribersLock.Unlock() + + uid, err := uuid.NewUUID() + if err != nil { + panic(err) + } + id := uid.String() + + _, ok := gq.subscribers[messageType] + if !ok { + messageTypeSubscribers := make( + map[string]func(ctx context.Context, item *QueueMessage) error, + ) + messageTypeSubscribers[id] = callback + gq.subscribers[messageType] = messageTypeSubscribers + } else { + gq.subscribers[messageType][id] = callback + } + + return id +} + +func (gq *GoQueue) Unsubscribe(messageType string, id string) { + gq.subscribersLock.Lock() + defer gq.subscribersLock.Unlock() + _, ok := gq.subscribers[messageType] + if !ok { + // No work to be done + return + } else { + delete(gq.subscribers[messageType], id) + } +} + +func (gq *GoQueue) Insert(messageType string, content any) error { + gq.queueLock.Lock() + defer gq.queueLock.Unlock() + + contents, err := json.Marshal(content) + if err != nil { + return err + } + + gq.queue = append(gq.queue, &QueueMessage{ + Type: messageType, + Content: string(contents), + }) + + go func() { + gq.handle(context.Background()) + }() + + return nil +} + +func (gq *GoQueue) handle(ctx context.Context) { + gq.queueLock.Lock() + defer gq.queueLock.Unlock() + + for { + if len(gq.queue) == 0 { + return + } + + item := gq.queue[0] + gq.queue = gq.queue[1:] + + gq.subscribersLock.RLock() + defer gq.subscribersLock.RUnlock() + + for id, callback := range gq.subscribers[item.Type] { + log.Printf("sending message to %s", id) + go callback(ctx, item) + } + } +} + +type GiteaClient struct { + url *string + token *string + + client *http.Client +} + +func NewGiteaClient(url, token *string) *GiteaClient { + return &GiteaClient{ + url: url, + token: token, + client: http.DefaultClient, + } +} + +func (gc *GiteaClient) EditComment( + ctx context.Context, + doneRequest *RefreshDoneRepositoryRequest, +) error { + commentBody := html.UnescapeString(doneRequest.CommentBody) + startCmnt := "" + startIdx := strings.Index(commentBody, startCmnt) + endIdx := strings.Index(commentBody, "") + if startIdx >= 0 && endIdx >= 0 { + log.Println("found comment to replace") + + var content string + + if doneRequest.Error != "" { + content = fmt.Sprintf("
ERROR: %s

", doneRequest.Error) + } + if doneRequest.Status != "" { + content = fmt.Sprintf("

%s

", doneRequest.Status) + } + + doneRequest.CommentBody = fmt.Sprintf( + "%s

%s

%s", + commentBody[:startIdx+len(startCmnt)], + content, + commentBody[endIdx:], + ) + } + + editComment := struct { + Body string `json:"body"` + }{ + Body: doneRequest.CommentBody, + } + + body, err := json.Marshal(editComment) + if err != nil { + log.Println("failed to marshal request body: %w", err) + return err + } + bodyReader := bytes.NewReader(body) + + request, err := http.NewRequest( + http.MethodPatch, + fmt.Sprintf( + "%s/repos/%s/%s/issues/comments/%d", + strings.TrimSuffix(*gc.url, "/"), + doneRequest.Owner, + doneRequest.Repository, + doneRequest.CommentID, + ), + bodyReader, + ) + if err != nil { + log.Printf("failed to form update comment request: %s", err.Error()) + return err + } + request.Header.Add("Authorization", fmt.Sprintf("token %s", *gc.token)) + request.Header.Add("Content-Type", "application/json") + + resp, err := gc.client.Do(request) + if err != nil { + log.Printf("failed to update comment: %s", err.Error()) + return err + } + + if resp.StatusCode > 299 { + log.Printf("failed to update comment with status code: %d", resp.StatusCode) + respBody, err := io.ReadAll(resp.Body) + if err != nil { + log.Printf("failed to read body of error response: %s", err.Error()) + } else { + log.Printf("request body: %s", string(respBody)) + } + } + + return nil +} + +func (gc *GiteaClient) CreateWebhook(owner, repository string) error { + createHookOptions := createHook{ + Active: true, + AuthorizationHeader: "", + BranchFilter: "*", + Config: map[string]string{ + "url": "http://10.0.9.1:8080/gitea/webhook", + "content_type": "json", + }, + Events: []string{ + "pull_request_comment", + }, + Type: "gitea", + } + + body, err := json.Marshal(createHookOptions) + if err != nil { + log.Println("failed to marshal request body: %w", err) + return err + } + bodyReader := bytes.NewReader(body) + request, err := http.NewRequest( + http.MethodPost, + fmt.Sprintf( + "%s/repos/%s/%s/hooks", + strings.TrimSuffix(*gc.url, "/"), + owner, + repository, + ), + bodyReader, + ) + if err != nil { + log.Printf("failed to form create hook request: %s", err.Error()) + return err + } + request.Header.Add("Authorization", fmt.Sprintf("token %s", *gc.token)) + request.Header.Add("Content-Type", "application/json") + + resp, err := gc.client.Do(request) + if err != nil { + log.Printf("failed to register hook: %s", err.Error()) + return err + } + + if resp.StatusCode > 299 { + log.Printf("failed to register with status code: %d", resp.StatusCode) + respBody, err := io.ReadAll(resp.Body) + if err != nil { + log.Printf("failed to read body of error response: %s", err.Error()) + } else { + log.Printf("request body: %s", string(respBody)) + } + } + + return nil +} + +func (gc *GiteaClient) AddComment( + owner, repository string, + pullRequest int, + comment string, +) (*AddCommentResponse, error) { + addComment := struct { + Body string `json:"body"` + }{ + Body: comment, + } + + body, err := json.Marshal(addComment) + if err != nil { + return nil, err + } + bodyReader := bytes.NewReader(body) + + request, err := http.NewRequest( + http.MethodPost, + fmt.Sprintf( + "%s/repos/%s/%s/issues/%d/comments", + strings.TrimSuffix(*gc.url, "/"), + owner, + repository, + pullRequest, + ), + bodyReader, + ) + if err != nil { + return nil, err + } + request.Header.Add("Authorization", fmt.Sprintf("token %s", *gc.token)) + request.Header.Add("Content-Type", "application/json") + + resp, err := gc.client.Do(request) + if err != nil { + return nil, err + } + + if resp.StatusCode > 299 { + log.Printf("failed to register with status code: %d", resp.StatusCode) + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } else { + log.Printf("request body: %s", string(respBody)) + } + } + + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + var response AddCommentResponse + if err := json.Unmarshal(respBody, &response); err != nil { + return nil, err + } + + return &response, nil +} + +type RenovateClient struct { + config string +} + +func NewRenovateClient(config string) *RenovateClient { + return &RenovateClient{config: config} +} + +func (rc *RenovateClient) RefreshRepository(ctx context.Context, owner, repository string) error { + client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stdout)) + if err != nil { + return err + } + + envRenovateToken := os.Getenv("GITEA_RENOVATE_TOKEN") + log.Println(envRenovateToken) + + renovateToken := client.SetSecret("RENOVATE_TOKEN", envRenovateToken) + githubComToken := client.SetSecret("GITHUB_COM_TOKEN", os.Getenv("GITHUB_COM_TOKEN")) + renovateSecret := client.SetSecret("RENOVATE_SECRETS", os.Getenv("RENOVATE_SECRETS")) + + output, err := client.Container(). + From("renovate/renovate:latest"). + WithNewFile("/opts/renovate/config.json", dagger.ContainerWithNewFileOpts{ + Contents: `{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "platform": "gitea", + "endpoint": "https://git.front.kjuulh.io/api/v1/", + "automerge": true, + "automergeType": "pr", + "extends": [ + "config:base" + ], + "hostRules": [ + { + "hostType": "docker", + "matchHost": "harbor.front.kjuulh.io", + "username": "service", + "password": "{{ secrets.HARBOR_SERVER_PASSWORD }}" + } + ], + "packageRules": [ + { + "matchDatasources": ["docker"], + "registryUrls": ["https://harbor.front.kjuulh.io/docker-proxy/library/"] + }, + { + "groupName": "all dependencies", + "separateMajorMinor": false, + "groupSlug": "all", + "packageRules": [ + { + "matchPackagePatterns": [ + "*" + ], + "groupName": "all dependencies", + "groupSlug": "all" + } + ], + "lockFileMaintenance": { + "enabled": false + } + } + ] +}`, + Permissions: 755, + Owner: "root", + }). + WithSecretVariable("RENOVATE_TOKEN", renovateToken). + WithSecretVariable("GITHUB_COM_TOKEN", githubComToken). + WithSecretVariable("RENOVATE_SECRETS", renovateSecret). + WithEnvVariable("LOG_LEVEL", "warn"). + WithEnvVariable("RENOVATE_CONFIG_FILE", "/opts/renovate/config.json"). + WithExec([]string{ + fmt.Sprintf("%s/%s", owner, repository), + }). + Sync(ctx) + + stdout, outerr := output.Stdout(ctx) + if outerr == nil { + log.Printf("stdout: %s", stdout) + } + stderr, outerr := output.Stderr(ctx) + if outerr == nil { + log.Printf("stderr: %s", stderr) + } + if err != nil { + return fmt.Errorf("error: %w, \nstderr: %s\nstdout: %s", err, stderr, stdout) + } + + return nil +} diff --git a/go.mod b/go.mod index ddde2ba..eb76840 100644 --- a/go.mod +++ b/go.mod @@ -3,15 +3,26 @@ module git.front.kjuulh.io/kjuulh/contractor go 1.20 require ( + dagger.io/dagger v0.8.1 + github.com/gin-gonic/gin v1.9.1 + github.com/google/uuid v1.3.0 + github.com/joho/godotenv v1.5.1 + github.com/spf13/cobra v1.7.0 +) + +require ( + github.com/99designs/gqlgen v0.17.31 // indirect + github.com/Khan/genqlient v0.6.0 // indirect + github.com/adrg/xdg v0.4.0 // indirect github.com/bytedance/sonic v1.9.1 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect - github.com/gin-gonic/gin v1.9.1 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.14.0 // indirect github.com/goccy/go-json v0.10.2 // indirect + github.com/iancoleman/strcase v0.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect @@ -20,15 +31,18 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/spf13/cobra v1.7.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect + github.com/vektah/gqlparser/v2 v2.5.6 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.9.0 // indirect - golang.org/x/net v0.10.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.12.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/tools v0.11.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 8b0e31f..4a41eac 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,16 @@ +dagger.io/dagger v0.8.1 h1:jLNPGubxrLWUfsX+snjaw913B1lxVmWftzdVehB+RQU= +dagger.io/dagger v0.8.1/go.mod h1:CZwYt0FfVsEEYTFytzf2ihESB2P4H1S3/UfnrVxjBsE= +github.com/99designs/gqlgen v0.17.31 h1:VncSQ82VxieHkea8tz11p7h/zSbvHSxSDZfywqWt158= +github.com/99designs/gqlgen v0.17.31/go.mod h1:i4rEatMrzzu6RXaHydq1nmEPZkb3bKQsnxNRHS4DQB4= +github.com/Khan/genqlient v0.6.0 h1:Bwb1170ekuNIVIwTJEqvO8y7RxBxXu639VJOkKSrwAk= +github.com/Khan/genqlient v0.6.0/go.mod h1:rvChwWVTqXhiapdhLDV4bp9tz/Xvtewwkon4DpWWCRM= +github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= +github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= +github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= +github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= @@ -6,13 +19,16 @@ github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhD github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= 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.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= @@ -22,15 +38,27 @@ github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QX github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= +github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +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/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= @@ -42,8 +70,11 @@ 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/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -52,34 +83,50 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/vektah/gqlparser/v2 v2.5.6 h1:Ou14T0N1s191eRMZ1gARVqohcbe1e8FrcONScsq8cRU= +github.com/vektah/gqlparser/v2 v2.5.6/go.mod h1:z8xXUff237NntSuH8mLFijZ+1tjV1swDbpDqjJmk6ME= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= +golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index efd59d9..56dcde2 100644 --- a/main.go +++ b/main.go @@ -4,9 +4,15 @@ import ( "log" "git.front.kjuulh.io/kjuulh/contractor/cmd/contractor" + "github.com/joho/godotenv" ) func main() { + err := godotenv.Load() + if err != nil { + log.Println("DEBUG: no .env file found") + } + if err := contractor.RootCmd().Execute(); err != nil { log.Fatal(err) } -- 2.45.2 From d6dab34184e2c79827d29d11f0dfd8a65ffc2159 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Tue, 8 Aug 2023 14:44:00 +0200 Subject: [PATCH 03/74] feat: add basic readme Signed-off-by: kjuulh --- README.md | 94 +++++++++++++++++++++++++++++++++++++++++++++ assets/command.png | Bin 0 -> 42688 bytes 2 files changed, 94 insertions(+) create mode 100644 README.md create mode 100644 assets/command.png diff --git a/README.md b/README.md new file mode 100644 index 0000000..414bf4c --- /dev/null +++ b/README.md @@ -0,0 +1,94 @@ +# Contractor - A renovate bot for gitea and github + +Contractor is a chatops like bot, integrating with github/gitea issues, allowing commands to trigger renovate runs. + +```bash +/contractor refresh +``` + +Contractor runs in a regular docker image and uses the official renovate slim image behind the scenes, this can be changed in the configuration. + +![command](./assets/command.png) + +## Getting started + +First you need to pull and run the contractor image, docker is the preferred way of execution, but golang is also available from source. + +Docker compose is given as an example, but you're free to run using `docker run` if you prefer. + +See example for a ready-to-run image + +```yaml +# file: docker-compose.yaml +version: "3" +services: + contractor: + image: docker.io/kjuulh/contractor:latest + restart: unless-stopped + commands: + - contractor server serve + volumes: + - "./templates/contractor:/mnt/config" + - "/var/run/docker.sock:/var/run/docker.sock" + env_file: + - .env +``` + +```bash +# file: .env +GITEA_RENOVATE_TOKEN= # needs repo and pull request permissions +GITHUB_RENOVATE_TOKEN= # needs repo and pull request permissions +GITHUB_COM_TOKEN= # used for communication, doesn't need much +RENOVATE_SECRETS='{"HARBOR_SERVER_PASSWORD": ""}' +CONTRACTOR_API_KEY='' +``` + +```json +// file: templates/contractor/config.json +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "platform": "gitea", + "extends": [ + "config:base" + ] +} +// Remember to fill out the options as you see fit, this is not a complete example +``` + +Use renovate secret for each `{{ secrets.HARBOR_SERVER_PASSWORD }}` in your config, replace `HARBOR_SERVER_PASSWORD` with your own + +And then run the server with: `docker compose up` + +This has started the server, but github doesn't know that it needs to talk to you yet. + +As such host the server somewhere with a public hostname, such that github or gitea webhooks can reach it, i.e. contractor.some-domain.com:9111 + +To install the webhook, either use the docker image, or download the cli from source. + +### CLI + +To install the cli + +```bash +go install git.front.kjuulh.io/kjuulh/contractor@latest +``` + +contractor will automatically read any .env file, so you can leave out the secrets. + +```bash +contractor install --owner kjuulh --repository contractor --url https://git.front.kjuulh.io/api/v1 --backend gitea +``` + +If you leave any of these out, contractor will prompt your for required values. + +### Docker + +You can also use docker for it. + +```bash +docker compose run contractor install --owner kjuulh --repository contractor --url https://git.front.kjuulh.io/api/v1 --backend gitea +``` + +### GitHub App + +TBD, this should automatically install the webhook for allowed repositories, I just haven't gotten around to it yet. It is on the 0.3.0 Roadmap. diff --git a/assets/command.png b/assets/command.png new file mode 100644 index 0000000000000000000000000000000000000000..f6bbcbd4eeafa35eec1b8a2ea850ae6226a8947a GIT binary patch literal 42688 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 Date: Tue, 8 Aug 2023 14:45:10 +0200 Subject: [PATCH 04/74] docs: clarification Signed-off-by: kjuulh --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 414bf4c..d835707 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Contractor is a chatops like bot, integrating with github/gitea issues, allowing Contractor runs in a regular docker image and uses the official renovate slim image behind the scenes, this can be changed in the configuration. ![command](./assets/command.png) +Do note that the contractor was run under a personal user, hence the same user replied ## Getting started @@ -34,6 +35,7 @@ services: - .env ``` + ```bash # file: .env GITEA_RENOVATE_TOKEN= # needs repo and pull request permissions -- 2.45.2 From 9cd29a6b106074733c7e63b42340f4857d0d786a Mon Sep 17 00:00:00 2001 From: kjuulh Date: Tue, 8 Aug 2023 14:45:27 +0200 Subject: [PATCH 05/74] docs: add license Signed-off-by: kjuulh --- LICENSE | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f6a730e --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +Copyright 2023 Kasper J. Hermansen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- 2.45.2 From 67b2b14567d908eda94ca002f4652f3278e73a15 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Tue, 8 Aug 2023 15:50:47 +0200 Subject: [PATCH 06/74] feat: add basic ci Signed-off-by: kjuulh --- .drone.yml | 171 +++ .gitignore | 2 + ci/Cargo.lock | 1902 ++++++++++++++++++++++++++++++++ ci/Cargo.toml | 16 + ci/src/main.rs | 537 +++++++++ cuddle.yaml | 27 + scripts/ci:main.sh | 23 + scripts/ci:pr.sh | 25 + scripts/local:docker.sh | 5 + scripts/local:docker:docs.sh | 5 + scripts/mkdocs:build.sh | 5 + scripts/mkdocs:dev.sh | 5 + scripts/mkdocs:new.sh | 5 + scripts/publish:docker:docs.sh | 1 + 14 files changed, 2729 insertions(+) create mode 100644 .drone.yml create mode 100644 ci/Cargo.lock create mode 100644 ci/Cargo.toml create mode 100644 ci/src/main.rs create mode 100644 cuddle.yaml create mode 100755 scripts/ci:main.sh create mode 100755 scripts/ci:pr.sh create mode 100755 scripts/local:docker.sh create mode 100755 scripts/local:docker:docs.sh create mode 100755 scripts/mkdocs:build.sh create mode 100755 scripts/mkdocs:dev.sh create mode 100755 scripts/mkdocs:new.sh create mode 100644 scripts/publish:docker:docs.sh diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..f7f8d7c --- /dev/null +++ b/.drone.yml @@ -0,0 +1,171 @@ +kind: pipeline +name: default +type: docker + +steps: + - name: build ci + image: rustlang/rust:nightly + volumes: + - name: ci + path: /mnt/ci + environment: + PKG_CONFIG_SYSROOT_DIR: "/" + CI_PREFIX: "/mnt/ci" + commands: + - set -e + - apt update + - apt install musl-tools pkg-config libssl-dev openssl build-essential musl-dev -y + - rustup target add x86_64-unknown-linux-musl + - cd ci + - cargo build --target=x86_64-unknown-linux-musl + #- cargo build -p ci + - mv target/x86_64-unknown-linux-musl/debug/ci "$CI_PREFIX/ci" + #- mv target/debug/ci $CI_PREFIX/ci + + - name: load_secret + image: debian:buster-slim + volumes: + - name: ssh + path: /root/.ssh/ + environment: + SSH_KEY: + from_secret: gitea_id_ed25519 + commands: + - mkdir -p $HOME/.ssh/ + - echo "$SSH_KEY" | base64 -d > $HOME/.ssh/id_ed25519 + + - name: build pr + image: kasperhermansen/cuddle:latest + pull: always + volumes: + - name: ssh + path: /root/.ssh/ + - name: dockersock + path: /var/run + - name: ci + path: /mnt/ci + commands: + - eval `ssh-agent` + - chmod -R 600 ~/.ssh + - ssh-add + - echo "$DOCKER_PASSWORD" | docker login --password-stdin --username="$DOCKER_USERNAME" docker.io + - ldd $CI_PREFIX + - apk add git + - cuddle x ci:pr + environment: + DOCKER_BUILDKIT: 1 + DOCKER_PASSWORD: + from_secret: docker_password + DOCKER_USERNAME: + from_secret: docker_username + CUDDLE_SECRETS_PROVIDER: 1password + CUDDLE_ONE_PASSWORD_DOT_ENV: ".env.ci" + CUDDLE_SSH_AGENT: "true" + CI_PREFIX: "/mnt/ci/ci" + CUDDLE_PLEASE_TOKEN: + from_secret: cuddle_please_token + OP_SERVICE_ACCOUNT_TOKEN: + from_secret: op_service_account_token + when: + event: + - pull_request + exclude: + - main + - master + depends_on: + - "load_secret" + - "build ci" + + - name: build main + image: kasperhermansen/cuddle:latest + pull: always + volumes: + - name: ssh + path: /root/.ssh/ + - name: dockersock + path: /var/run + - name: ci + path: /mnt/ci + commands: + - eval `ssh-agent` + - chmod -R 600 ~/.ssh + - ssh-add + - echo "$DOCKER_PASSWORD" | docker login --password-stdin --username="$DOCKER_USERNAME" docker.io + - ldd $CI_PREFIX + - apk add git + - cuddle x ci:main + environment: + DOCKER_BUILDKIT: 1 + DOCKER_PASSWORD: + from_secret: docker_password + DOCKER_USERNAME: + from_secret: docker_username + CUDDLE_SECRETS_PROVIDER: 1password + CUDDLE_ONE_PASSWORD_DOT_ENV: ".env.ci" + CUDDLE_SSH_AGENT: "true" + CI_PREFIX: "/mnt/ci/ci" + CUDDLE_PLEASE_TOKEN: + from_secret: cuddle_please_token + OP_SERVICE_ACCOUNT_TOKEN: + from_secret: op_service_account_token + when: + event: + - push + branch: + - main + - master + exclude: + - pull_request + depends_on: + - "load_secret" + - "build ci" + + - name: deploy release + image: kasperhermansen/cuddle:latest + pull: always + volumes: + - name: ssh + path: /root/.ssh/ + - name: dockersock + path: /var/run + commands: + - eval `ssh-agent` + - chmod -R 600 ~/.ssh + - ssh-add + - cuddle x build:release:all + - cuddle x deploy:docs:preview + environment: + DOCKER_BUILDKIT: 1 + CUDDLE_SECRETS_PROVIDER: 1password + CUDDLE_ONE_PASSWORD_DOT_ENV: ".env.ci" + CUDDLE_SSH_AGENT: "true" + CUDDLE_CI: "true" + CUDDLE_PLEASE_TOKEN: + from_secret: cuddle_please_token + OP_SERVICE_ACCOUNT_TOKEN: + from_secret: op_service_account_token + when: + event: + - tag + ref: + include: + - refs/tags/v* + depends_on: + - "load_secret" + - "build ci" + +services: +- name: docker + image: docker:dind + privileged: true + volumes: + - name: dockersock + path: /var/run + +volumes: + - name: ssh + temp: {} + - name: dockersock + temp: {} + - name: ci + temp: {} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 4c49bd7..b5cb2c5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .env +.cuddle/ +target/ diff --git a/ci/Cargo.lock b/ci/Cargo.lock new file mode 100644 index 0000000..200628f --- /dev/null +++ b/ci/Cargo.lock @@ -0,0 +1,1902 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "anstream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" + +[[package]] +name = "anstyle-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "ascii" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" + +[[package]] +name = "async-scoped" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7a6a57c8aeb40da1ec037f5d455836852f7a57e69e1b1ad3d8f38ac1d6cadf" +dependencies = [ + "futures", + "pin-project", + "slab", + "tokio", +] + +[[package]] +name = "async-trait" +version = "0.1.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cc" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f1226cd9da55587234753d1245dd5b132343ea240f26b6a9003d68706141ba" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "ci" +version = "0.1.0" +dependencies = [ + "async-scoped", + "clap", + "color-eyre", + "dagger-sdk", + "dotenv", + "eyre", + "futures", + "tokio", +] + +[[package]] +name = "clap" +version = "4.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" +dependencies = [ + "clap_builder", + "clap_derive", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "clap_lex" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" + +[[package]] +name = "color-eyre" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba75b3d9449ecdccb27ecbc479fdc0b87fa2dd43d2f8298f9bf0e59aacc8dce" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "combine" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" +dependencies = [ + "ascii", + "byteorder", + "either", + "memchr", + "unreachable", +] + +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "dagger-core" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8af54bf8b7f93562405f62f5b724a322eeb1618c484010012f3293aa4832b16" +dependencies = [ + "async-trait", + "base64", + "dirs", + "eyre", + "flate2", + "graphql_client", + "hex", + "hex-literal", + "platform-info", + "reqwest", + "serde", + "serde_json", + "sha2", + "tar", + "tempfile", + "tokio", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "dagger-sdk" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc52e90df068815076f0d3ee0ed683bbbe8a4a30443b09a5ef7e0bcc4b6ce4bc" +dependencies = [ + "dagger-core", + "derive_builder", + "eyre", + "futures", + "serde", + "serde_json", + "tokio", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_macro" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" +dependencies = [ + "derive_builder_core", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "encoding_rs" +version = "0.8.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "errno" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "eyre" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + +[[package]] +name = "filetime" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.2.16", + "windows-sys", +] + +[[package]] +name = "flate2" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + +[[package]] +name = "graphql-introspection-query" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2a4732cf5140bd6c082434494f785a19cfb566ab07d1382c3671f5812fed6d" +dependencies = [ + "serde", +] + +[[package]] +name = "graphql-parser" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ebc8013b4426d5b81a4364c419a95ed0b404af2b82e2457de52d9348f0e474" +dependencies = [ + "combine", + "thiserror", +] + +[[package]] +name = "graphql_client" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa61bb9dc6d373a8b465a5da17b62809483e8527a34b0e9034dc0915b09e160a" +dependencies = [ + "graphql_query_derive", + "reqwest", + "serde", + "serde_json", +] + +[[package]] +name = "graphql_client_codegen" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e55df64cc702c4ad6647f8df13a799ad11688a3781fadf5045f7ba12733fa9b" +dependencies = [ + "graphql-introspection-query", + "graphql-parser", + "heck", + "lazy_static", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn 1.0.109", +] + +[[package]] +name = "graphql_query_derive" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52fc9cde811f44b15ec0692b31e56a3067f6f431c5ace712f286e47c1dacc98" +dependencies = [ + "graphql_client_codegen", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "h2" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "ipnet" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "linux-raw-sys" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" + +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.3.5", + "smallvec", + "windows-targets", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "platform-info" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7c23cfae725ae06d9e43010153fa77bdfa8c827bf08fe4beeb2a3514e6be12" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall 0.2.16", + "thiserror", +] + +[[package]] +name = "reqwest" +version = "0.11.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-rustls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustls" +version = "0.21.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +dependencies = [ + "base64", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513722fd73ad80a71f72b61009ea1b584bcfa1483ca93949c8f290298837fa59" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "serde" +version = "1.0.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea67f183f058fe88a4e3ec6e2788e003840893b91bac4559cabedd00863b3ed" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24e744d7782b686ab3b73267ef05697159cc0e5abbed3f47f9933165e5219036" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "serde_json" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tar" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec96d2ffad078296368d46ff1cb309be1c23c513b4ab0e22a45de0185275ac96" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tempfile" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.3.5", + "rustix", + "windows-sys", +] + +[[package]] +name = "thiserror" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +dependencies = [ + "autocfg", + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +dependencies = [ + "void", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.28", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "wasm-streams" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + +[[package]] +name = "xattr" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" +dependencies = [ + "libc", +] diff --git a/ci/Cargo.toml b/ci/Cargo.toml new file mode 100644 index 0000000..0cdb923 --- /dev/null +++ b/ci/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "ci" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +dagger-sdk = "*" +eyre = "*" +color-eyre = "*" +tokio = "1" +clap = {version = "4", features = ["derive"]} +futures = "0.3.28" +async-scoped = { version = "0.7.1", features = ["tokio", "use-tokio"] } +dotenv = "*" diff --git a/ci/src/main.rs b/ci/src/main.rs new file mode 100644 index 0000000..b4827fb --- /dev/null +++ b/ci/src/main.rs @@ -0,0 +1,537 @@ +use std::path::PathBuf; +use std::sync::Arc; + +use clap::Args; +use clap::Parser; +use clap::Subcommand; +use clap::ValueEnum; + +use dagger_sdk::Platform; +use dagger_sdk::QueryContainerOpts; + +use crate::please_release::run_release_please; + +#[derive(Parser, Clone)] +#[command(author, version, about, long_about = None, subcommand_required = true)] +pub struct Command { + #[command(subcommand)] + commands: Commands, + + #[command(flatten)] + global: GlobalArgs, +} + +#[derive(Subcommand, Clone)] +pub enum Commands { + PullRequest { + #[arg(long)] + image: String, + #[arg(long)] + tag: String, + #[arg(long)] + bin_name: String, + }, + Main { + #[arg(long)] + image: String, + #[arg(long)] + tag: String, + #[arg(long)] + bin_name: String, + }, + Release, +} + +#[derive(Subcommand, Clone)] +pub enum LocalCommands { + Build { + #[arg(long, default_value = "debug")] + profile: BuildProfile, + #[arg(long)] + bin_name: String, + }, + Test, + DockerImage { + #[arg(long)] + image: String, + #[arg(long)] + tag: String, + #[arg(long)] + bin_name: String, + }, + PleaseRelease, + BuildDocs {}, +} + +#[derive(Debug, Clone, ValueEnum)] +pub enum BuildProfile { + Debug, + Release, +} + +#[derive(Debug, Clone, Args)] +pub struct GlobalArgs { + #[arg(long, global = true, help_heading = "Global")] + dry_run: bool, + + #[arg(long, global = true, help_heading = "Global")] + golang_builder_image: Option, + + #[arg(long, global = true, help_heading = "Global")] + production_image: Option, + + #[arg(long, global = true, help_heading = "Global")] + docker_image: Option, + + #[arg(long, global = true, help_heading = "Global")] + source: Option, + + #[arg(long, global = true, help_heading = "Global")] + docs_image: Option, + + #[arg(long, global = true, help_heading = "Global")] + docs_image_tag: Option, +} + +#[tokio::main] +async fn main() -> eyre::Result<()> { + let _ = dotenv::dotenv(); + let _ = color_eyre::install(); + + let client = dagger_sdk::connect().await?; + + let cli = Command::parse(); + + match &cli.commands { + Commands::PullRequest { + image, + tag, + bin_name, + } => { + async fn test(client: Arc, cli: &Command, bin_name: &String) { + let args = &cli.global; + + let base_image = base_golang_image(client.clone(), args, &None, bin_name) + .await + .unwrap(); + test::execute(client.clone(), args, base_image) + .await + .unwrap(); + } + async fn build( + client: Arc, + cli: &Command, + bin_name: &String, + image: &String, + tag: &String, + ) { + let args = &cli.global; + + build::build(client.clone(), args, bin_name, image, tag) + .await + .unwrap(); + } + + tokio::join!( + test(client.clone(), &cli, bin_name), + build(client.clone(), &cli, bin_name, image, tag), + ); + } + Commands::Main { + image, + tag, + bin_name, + } => { + async fn test(client: Arc, cli: &Command, bin_name: &String) { + let args = &cli.global; + + let base_image = base_golang_image(client.clone(), args, &None, bin_name) + .await + .unwrap(); + test::execute(client.clone(), args, base_image) + .await + .unwrap(); + } + async fn build( + client: Arc, + cli: &Command, + bin_name: &String, + image: &String, + tag: &String, + ) { + let args = &cli.global; + + build::build_and_deploy(client.clone(), args, bin_name, image, tag) + .await + .unwrap(); + } + + async fn cuddle_please(client: Arc, cli: &Command) { + run_release_please(client.clone(), &cli.global) + .await + .unwrap(); + } + + tokio::join!( + test(client.clone(), &cli, bin_name), + build(client.clone(), &cli, bin_name, image, tag), + cuddle_please(client.clone(), &cli) + ); + } + Commands::Release => todo!(), + } + + Ok(()) +} + +mod please_release { + use std::sync::Arc; + + use crate::GlobalArgs; + + pub async fn run_release_please( + client: Arc, + _args: &GlobalArgs, + ) -> eyre::Result<()> { + let build_image = client + .container() + .from("kasperhermansen/cuddle-please:main-1691463075"); + + let src = client + .git_opts( + "https://git.front.kjuulh.io/kjuulh/contractor", + dagger_sdk::QueryGitOpts { + experimental_service_host: None, + keep_git_dir: Some(true), + }, + ) + .branch("main") + .tree(); + + let res = build_image + .with_secret_variable( + "CUDDLE_PLEASE_TOKEN", + client + .set_secret("CUDDLE_PLEASE_TOKEN", std::env::var("CUDDLE_PLEASE_TOKEN")?) + .id() + .await?, + ) + .with_workdir("/mnt/app") + .with_directory(".", src.id().await?) + .with_exec(vec![ + "git", + "remote", + "set-url", + "origin", + &format!( + "https://git:{}@git.front.kjuulh.io/kjuulh/contractor.git", + std::env::var("CUDDLE_PLEASE_TOKEN")? + ), + ]) + .with_exec(vec![ + "cuddle-please", + "release", + "--engine=gitea", + "--owner=kjuulh", + "--repo=contractor", + "--branch=main", + "--api-url=https://git.front.kjuulh.io", + "--log-level=debug", + ]); + + let exit_code = res.exit_code().await?; + if exit_code != 0 { + eyre::bail!("failed to run cuddle-please"); + } + + let please_out = res.stdout().await?; + println!("{please_out}"); + let please_out = res.stderr().await?; + println!("{please_out}"); + + Ok(()) + } +} + +mod build { + use std::sync::Arc; + + use dagger_sdk::Container; + + use crate::{base_golang_image, get_base_debian_image, GlobalArgs}; + + pub async fn build_and_deploy( + client: Arc, + args: &GlobalArgs, + bin_name: &String, + image: &String, + tag: &String, + ) -> eyre::Result<()> { + // let containers = vec!["linux/amd64", "linux/arm64"]; + + let base_image = get_base_debian_image( + client.clone(), + &args.clone(), + Some("linux/amd64".to_string()), + ) + .await?; + + let container = base_golang_image( + client.clone(), + args, + &Some("linux/amd64".to_string()), + &bin_name.clone(), + ) + .await?; + let build_image = execute(client.clone(), args, &container, &base_image, bin_name).await?; + + let build_id = build_image.id().await?; + + let _container = client + .clone() + .container() + .publish_opts( + format!("{image}:{tag}"), + dagger_sdk::ContainerPublishOpts { + platform_variants: Some(vec![build_id]), + }, + ) + .await?; + Ok(()) + } + pub async fn build( + client: Arc, + args: &GlobalArgs, + bin_name: &String, + _image: &String, + _tag: &String, + ) -> eyre::Result<()> { + // let containers = vec!["linux/amd64", "linux/arm64"]; + + let base_image = get_base_debian_image( + client.clone(), + &args.clone(), + Some("linux/amd64".to_string()), + ) + .await?; + + let container = base_golang_image( + client.clone(), + args, + &Some("linux/amd64".to_string()), + &bin_name.clone(), + ) + .await?; + let build_image = execute(client.clone(), args, &container, &base_image, bin_name).await?; + + build_image.exit_code().await?; + + Ok(()) + } + pub async fn execute( + _client: Arc, + _args: &GlobalArgs, + container: &dagger_sdk::Container, + base_image: &dagger_sdk::Container, + bin_name: &String, + ) -> eyre::Result { + let final_image = base_image + .with_file( + format!("/usr/local/bin/{}", &bin_name), + container + .file(format!("/mnt/src/dist/{}", &bin_name)) + .id() + .await?, + ) + .with_exec(vec![bin_name, "--help"]); + + let output = final_image.stdout().await?; + println!("{output}"); + + Ok(final_image) + } +} + +mod test { + use std::sync::Arc; + + use crate::GlobalArgs; + + pub async fn execute( + _client: Arc, + args: &GlobalArgs, + container: dagger_sdk::Container, + ) -> eyre::Result<()> { + let test_image = container + .pipeline("test") + .with_exec(vec!["go", "test", "./..."]); + + test_image.exit_code().await?; + + Ok(()) + } +} + +pub async fn get_base_docker_image( + client: Arc, + args: &GlobalArgs, + platform: Option, +) -> eyre::Result { + let default_platform = client.default_platform().await?; + let platform = platform.map(Platform).unwrap_or(default_platform); + + let image = client + .container_opts(QueryContainerOpts { + id: None, + platform: Some(platform), + }) + .from( + args.docker_image + .clone() + .unwrap_or("docker:dind".to_string()), + ); + + Ok(image) +} + +pub async fn get_base_debian_image( + client: Arc, + args: &GlobalArgs, + platform: Option, +) -> eyre::Result { + let docker_image = get_base_docker_image(client.clone(), args, platform.clone()).await?; + + let default_platform = client.default_platform().await?; + let platform = platform.map(Platform).unwrap_or(default_platform); + + let image = client + .container_opts(QueryContainerOpts { + id: None, + platform: Some(platform), + }) + .from( + args.production_image + .clone() + .unwrap_or("alpine:latest".to_string()), + ); + + let base_image = image + .with_exec(vec!["apk", "add", "openssl", "openssl-dev", "pkgconfig"]) + .with_file( + "/usr/local/bin/docker", + docker_image.file("/usr/local/bin/docker").id().await?, + ); + + Ok(base_image) +} + +pub fn get_src( + client: Arc, + args: &GlobalArgs, +) -> eyre::Result { + let directory = client.host().directory_opts( + args.source + .clone() + .unwrap_or(PathBuf::from(".")) + .display() + .to_string(), + dagger_sdk::HostDirectoryOptsBuilder::default() + .exclude(vec![ + "node_modules/", + ".git/", + "target/", + ".cuddle/", + "docs/", + "ci/", + ]) + .build()?, + ); + + Ok(directory) +} + +pub async fn get_golang_dep_src( + client: Arc, + args: &GlobalArgs, +) -> eyre::Result { + let directory = client.host().directory_opts( + args.source + .clone() + .unwrap_or(PathBuf::from(".")) + .display() + .to_string(), + dagger_sdk::HostDirectoryOptsBuilder::default() + .include(vec!["**/go.*"]) + .build()?, + ); + + Ok(directory) +} + +pub async fn base_golang_image( + client: Arc, + args: &GlobalArgs, + platform: &Option, + bin_name: &String, +) -> eyre::Result { + let dep_src = get_golang_dep_src(client.clone(), args).await?; + let src = get_src(client.clone(), args)?; + + let client = client.pipeline("golang_base_image"); + + let goarch = match platform + .clone() + .unwrap_or("linux/amd64".to_string()) + .as_str() + { + "linux/amd64" => "amd64", + "linux/arm64" => "arm64", + _ => eyre::bail!("architecture not supported"), + }; + let goos = match platform + .clone() + .unwrap_or("linux/amd64".to_string()) + .as_str() + { + "linux/amd64" => "linux", + "linux/arm64" => "linux", + _ => eyre::bail!("os not supported"), + }; + let golang_build_image = client + .container() + .from( + args.golang_builder_image + .as_ref() + .unwrap_or(&"golang:latest".into()), + ) + .with_env_variable("GOOS", goos) + .with_env_variable("GOARCH", goarch) + .with_env_variable("CGO_ENABLED", "0"); + + let golang_dep_download = golang_build_image + .with_directory("/mnt/src", dep_src.id().await?) + .with_exec(vec!["go", "mod", "download"]) + .with_mounted_cache( + "/root/go", + client.cache_volume("golang_mod_cache").id().await?, + ); + + let golang_bin = golang_build_image + .with_workdir("/mnt/src") + // .with_directory( + // "/root/go", + // golang_dep_download.directory("/root/go").id().await?, + // ) + .with_directory("/mnt/src/", src.id().await?) + .with_exec(vec![ + "go", + "build", + "-o", + &format!("dist/{bin_name}"), + "main.go", + ]); + + golang_bin.exit_code().await?; + + Ok(golang_bin) +} diff --git a/cuddle.yaml b/cuddle.yaml new file mode 100644 index 0000000..5eed9cd --- /dev/null +++ b/cuddle.yaml @@ -0,0 +1,27 @@ +# yaml-language-server: $schema=https://git.front.kjuulh.io/kjuulh/cuddle/raw/branch/main/schemas/base.json + +base: "git@git.front.kjuulh.io:kjuulh/cuddle-golang-service-plan.git" + +vars: + service: "contractor" + registry: kasperhermansen + docker_image: "docker:dind" + golang_builder_image: "golang:latest" + production_image: "alpine:latest" + +please: + project: + owner: kjuulh + repository: contractor + branch: main + settings: + api_url: https://git.front.kjuulh.io + +scripts: + "ci:main": + type: shell + "ci:pr": + type: shell + "ci:release": + type: shell + \ No newline at end of file diff --git a/scripts/ci:main.sh b/scripts/ci:main.sh new file mode 100755 index 0000000..5cd0d69 --- /dev/null +++ b/scripts/ci:main.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -e + +CMD_PREFIX="" + +if [[ -n "$CI_PREFIX" ]]; then + CMD_PREFIX="$CI_PREFIX" +else + cd ci || return 1 + cargo build + cd - || return 1 + CMD_PREFIX="ci/target/debug/ci" +fi + + +$CMD_PREFIX main \ + --docker-image "$DOCKER_IMAGE" \ + --golang-builder-image "$GOLANG_BUILDER_IMAGE" \ + --production-image "$PRODUCTION_IMAGE" \ + --image "$REGISTRY/$SERVICE" \ + --tag "main-$(date +%s)" \ + --bin-name "$SERVICE" \ No newline at end of file diff --git a/scripts/ci:pr.sh b/scripts/ci:pr.sh new file mode 100755 index 0000000..adb7ff8 --- /dev/null +++ b/scripts/ci:pr.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +set -e + +CMD_PREFIX="cargo run -p ci --" + +CMD_PREFIX="" + +if [[ -n "$CI_PREFIX" ]]; then + CMD_PREFIX="$CI_PREFIX" +else + cd ci || return 1 + cargo build + cd - || return 1 + CMD_PREFIX="ci/target/debug/ci" +fi + + +$CMD_PREFIX pull-request \ + --docker-image "$DOCKER_IMAGE" \ + --golang-builder-image "$GOLANG_BUILDER_IMAGE" \ + --production-image "$PRODUCTION_IMAGE" \ + --image "$REGISTRY/$SERVICE" \ + --tag "main-$(date +%s)" \ + --bin-name "$SERVICE" \ No newline at end of file diff --git a/scripts/local:docker.sh b/scripts/local:docker.sh new file mode 100755 index 0000000..92693dc --- /dev/null +++ b/scripts/local:docker.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -e + +cargo run -p ci -- local docker-image --image kasperhermansen/cuddle-please --tag dev --bin-name cuddle-please diff --git a/scripts/local:docker:docs.sh b/scripts/local:docker:docs.sh new file mode 100755 index 0000000..4002ca9 --- /dev/null +++ b/scripts/local:docker:docs.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -e + +cargo run -p ci -- local build-docs --mkdocs-image $MKDOCS_IMAGE --caddy-image $CADDY_IMAGE diff --git a/scripts/mkdocs:build.sh b/scripts/mkdocs:build.sh new file mode 100755 index 0000000..af5a5e4 --- /dev/null +++ b/scripts/mkdocs:build.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -e + +docker run --rm -it -p 8000:8000 -v ${PWD}:/docs ${MKDOCS_IMAGE} diff --git a/scripts/mkdocs:dev.sh b/scripts/mkdocs:dev.sh new file mode 100755 index 0000000..af5a5e4 --- /dev/null +++ b/scripts/mkdocs:dev.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -e + +docker run --rm -it -p 8000:8000 -v ${PWD}:/docs ${MKDOCS_IMAGE} diff --git a/scripts/mkdocs:new.sh b/scripts/mkdocs:new.sh new file mode 100755 index 0000000..8410ed1 --- /dev/null +++ b/scripts/mkdocs:new.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -e + +docker run --rm -it -v ${PWD}:/docs ${MKDOCS_IMAGE} new . diff --git a/scripts/publish:docker:docs.sh b/scripts/publish:docker:docs.sh new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/scripts/publish:docker:docs.sh @@ -0,0 +1 @@ + -- 2.45.2 From 6132978c1f379814a57ba03d67f919841e7be068 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Tue, 8 Aug 2023 13:51:12 +0000 Subject: [PATCH 07/74] Add renovate.json --- renovate.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 renovate.json diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..7190a60 --- /dev/null +++ b/renovate.json @@ -0,0 +1,3 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json" +} -- 2.45.2 From 9db86258fd5beb03e36b5124fc2fe1b9f0f86499 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Tue, 8 Aug 2023 15:58:54 +0200 Subject: [PATCH 08/74] docs: add clarification about expectations and what milestones are missing Signed-off-by: kjuulh --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index d835707..ddbe1e2 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,23 @@ Contractor runs in a regular docker image and uses the official renovate slim im ![command](./assets/command.png) Do note that the contractor was run under a personal user, hence the same user replied +## DISCLAIMER + +The project is still 0.x.x As such the api is subject to change, and the examples will probably be out of date. The below should be seen as an example of what the project will look like once feature-complete. + +## Milestones + +- [x] 0.1.0 + - Includes basic setup such as working server bot, and installation command, automation is missing however. Also only gitea support for now, because this is where the project initially is supposed to be in use. +- [ ] 0.2.0 + - Add GitHub support +- [ ] 0.3.0 + - Add Delegation support (not clustering, just delegation of renovate jobs) +- [ ] 0.4.0 + - Slack integration +- [ ] 0.5.0 + - GitHub App and such support + ## Getting started First you need to pull and run the contractor image, docker is the preferred way of execution, but golang is also available from source. -- 2.45.2 From 005433abeedb3212741afeaefac4567f663cd41a Mon Sep 17 00:00:00 2001 From: kjuulh Date: Tue, 8 Aug 2023 16:01:26 +0200 Subject: [PATCH 09/74] docs(README): added some more milestones and fixed docker-compose Signed-off-by: kjuulh --- README.md | 79 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index ddbe1e2..f1e4f61 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,31 @@ # Contractor - A renovate bot for gitea and github -Contractor is a chatops like bot, integrating with github/gitea issues, allowing commands to trigger renovate runs. +Contractor is a chatops like bot, integrating with github/gitea issues, allowing +commands to trigger renovate runs. ```bash -/contractor refresh +/contractor refresh ``` -Contractor runs in a regular docker image and uses the official renovate slim image behind the scenes, this can be changed in the configuration. +Contractor runs in a regular docker image and uses the official renovate slim +image behind the scenes, this can be changed in the configuration. ![command](./assets/command.png) -Do note that the contractor was run under a personal user, hence the same user replied +Do note that the contractor was run under a personal user, hence the same +user replied ## DISCLAIMER -The project is still 0.x.x As such the api is subject to change, and the examples will probably be out of date. The below should be seen as an example of what the project will look like once feature-complete. +The project is still 0.x.x As such the api is subject to change, and the +examples will probably be out of date. The below should be seen as an example of +what the project will look like once feature-complete. ## Milestones - [x] 0.1.0 - - Includes basic setup such as working server bot, and installation command, automation is missing however. Also only gitea support for now, because this is where the project initially is supposed to be in use. + - Includes basic setup such as working server bot, and installation command, + automation is missing however. Also only gitea support for now, because this + is where the project initially is supposed to be in use. - [ ] 0.2.0 - Add GitHub support - [ ] 0.3.0 @@ -27,12 +34,16 @@ The project is still 0.x.x As such the api is subject to change, and the example - Slack integration - [ ] 0.5.0 - GitHub App and such support +- [ ] 0.6.0 + - Add api key support ## Getting started -First you need to pull and run the contractor image, docker is the preferred way of execution, but golang is also available from source. +First you need to pull and run the contractor image, docker is the preferred way +of execution, but golang is also available from source. -Docker compose is given as an example, but you're free to run using `docker run` if you prefer. +Docker compose is given as an example, but you're free to run using `docker run` +if you prefer. See example for a ready-to-run image @@ -41,18 +52,17 @@ See example for a ready-to-run image version: "3" services: contractor: - image: docker.io/kjuulh/contractor:latest - restart: unless-stopped - commands: - - contractor server serve - volumes: - - "./templates/contractor:/mnt/config" - - "/var/run/docker.sock:/var/run/docker.sock" - env_file: - - .env + image: docker.io/kjuulh/contractor:latest + restart: unless-stopped + commands: + - contractor server serve + volumes: + - "./templates/contractor:/mnt/config" + - "/var/run/docker.sock:/var/run/docker.sock" + env_file: + - .env ``` - ```bash # file: .env GITEA_RENOVATE_TOKEN= # needs repo and pull request permissions @@ -74,28 +84,37 @@ CONTRACTOR_API_KEY=' Date: Tue, 8 Aug 2023 14:02:12 +0000 Subject: [PATCH 10/74] chore(release): 0.1.0 --- CHANGELOG.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..82ccccf --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,29 @@ +# 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.1.0] - 2023-08-08 + +### Added +- add basic ci +- add basic readme +- with main loop +- with initial cmd and server + +### Docs +- *(README)* added some more milestones and fixed docker-compose +- add clarification about expectations and what milestones are missing +- add license +- clarification + +### Other +- Merge pull request 'Configure Renovate' (#1) from renovate/configure into main + +Reviewed-on: https://git.front.kjuulh.io/kjuulh/contractor/pulls/1 + +- Add renovate.json + -- 2.45.2 From 047f830b58cea379c013f1592b3705fd1bf387f1 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Tue, 8 Aug 2023 16:09:54 +0200 Subject: [PATCH 11/74] docs(README): add motivation why this project should exist Signed-off-by: kjuulh --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index f1e4f61..e104758 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,21 @@ image behind the scenes, this can be changed in the configuration. Do note that the contractor was run under a personal user, hence the same user replied +## Motivation + +Renovate by default if hosted yourself, is neither sharded, or runs on a +cron-job cycle. This leaves a lot to be desired from a developers point of view. +As it may take quite a long time for renovate to revisit the pull-request again, +if there is a lot of repositories enabled. + +This project intends to add an ad-hoc invocation of renovate for a single +repository, this enables developers to retrigger renovate whenever they want. + +The project is built to be integrated with github and gitea (initially), and +work in its pull-request system, so when a renovate pr shows up, you can either +manually retrigger it, or enable any of the options in the renovate dashboard, +and retrigger. + ## DISCLAIMER The project is still 0.x.x As such the api is subject to change, and the -- 2.45.2 From 4c095d62e3089b5c453851f9585f387a40b33a34 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Tue, 8 Aug 2023 16:20:29 +0200 Subject: [PATCH 12/74] chore(cuddle-please): update Signed-off-by: kjuulh --- ci/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/src/main.rs b/ci/src/main.rs index b4827fb..180436e 100644 --- a/ci/src/main.rs +++ b/ci/src/main.rs @@ -195,7 +195,7 @@ mod please_release { ) -> eyre::Result<()> { let build_image = client .container() - .from("kasperhermansen/cuddle-please:main-1691463075"); + .from("kasperhermansen/cuddle-please:main-1691504183"); let src = client .git_opts( -- 2.45.2 From d721b74d0564c168375ea4bfbf1ba3e4d01221f7 Mon Sep 17 00:00:00 2001 From: cuddle-please Date: Tue, 8 Aug 2023 14:22:50 +0000 Subject: [PATCH 13/74] chore(release): 0.1.1 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82ccccf..cb4775f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.1.1] - 2023-08-08 + +### Docs +- *(README)* add motivation why this project should exist + +### Other +- *(cuddle-please)* update + ## [0.1.0] - 2023-08-08 ### Added -- 2.45.2 From 65fba21285e646b8eeb7618e70a3b18ce68ef61a Mon Sep 17 00:00:00 2001 From: kjuulh Date: Tue, 8 Aug 2023 19:41:14 +0200 Subject: [PATCH 14/74] refactor(app): split the main command file into multiples Signed-off-by: kjuulh --- cmd/contractor/main.go | 674 +--------------------- internal/bot/giteabot.go | 67 +++ internal/features/handle_gitea_events.go | 84 +++ internal/features/handle_gitea_webhook.go | 83 +++ internal/models/requests.go | 40 ++ internal/providers/gitea.go | 227 ++++++++ internal/queue/goqueue.go | 113 ++++ internal/renovate/client.go | 103 ++++ 8 files changed, 738 insertions(+), 653 deletions(-) create mode 100644 internal/bot/giteabot.go create mode 100644 internal/features/handle_gitea_events.go create mode 100644 internal/features/handle_gitea_webhook.go create mode 100644 internal/models/requests.go create mode 100644 internal/providers/gitea.go create mode 100644 internal/queue/goqueue.go create mode 100644 internal/renovate/client.go diff --git a/cmd/contractor/main.go b/cmd/contractor/main.go index 5ad8051..792a690 100644 --- a/cmd/contractor/main.go +++ b/cmd/contractor/main.go @@ -1,34 +1,17 @@ package contractor import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "html" - "io" "log" - "net/http" - "os" - "strings" - "sync" - "time" - "dagger.io/dagger" "github.com/gin-gonic/gin" - "github.com/google/uuid" "github.com/spf13/cobra" -) -type createHook struct { - Active bool `json:"active"` - AuthorizationHeader string `json:"authorization_header"` - BranchFilter string `json:"branch_filter"` - Config map[string]string `json:"config"` - Events []string `json:"events"` - Type string `json:"type"` -} + "git.front.kjuulh.io/kjuulh/contractor/internal/bot" + "git.front.kjuulh.io/kjuulh/contractor/internal/features" + "git.front.kjuulh.io/kjuulh/contractor/internal/providers" + "git.front.kjuulh.io/kjuulh/contractor/internal/queue" + "git.front.kjuulh.io/kjuulh/contractor/internal/renovate" +) func installCmd() *cobra.Command { var ( @@ -44,7 +27,7 @@ func installCmd() *cobra.Command { Use: "install", Run: func(cmd *cobra.Command, args []string) { - if err := NewGiteaClient(&url, &token).CreateWebhook(owner, repository); err != nil { + if err := providers.NewGiteaClient(&url, &token).CreateWebhook(owner, repository); err != nil { log.Printf("failed to add create webhook: %s", err.Error()) } }, @@ -69,77 +52,14 @@ func serverCmd() *cobra.Command { token string ) - giteaClient := NewGiteaClient(&url, &token) - renovateClient := NewRenovateClient("") - queue := NewGoQueue() - queue.Subscribe( - MessageTypeRefreshRepository, - func(ctx context.Context, item *QueueMessage) error { - log.Printf("handling message: %s, content: %s", item.Type, item.Content) - return nil - }, - ) - queue.Subscribe( - MessageTypeRefreshRepositoryDone, - func(ctx context.Context, item *QueueMessage) error { - log.Printf("handling message: %s, content: %s", item.Type, item.Content) - return nil - }, - ) - queue.Subscribe( - MessageTypeRefreshRepository, - func(ctx context.Context, item *QueueMessage) error { - var request RefreshRepositoryRequest - if err := json.Unmarshal([]byte(item.Content), &request); err != nil { - log.Printf("failed to unmarshal request body: %s", err.Error()) - return err - } + giteaClient := providers.NewGiteaClient(&url, &token) + renovateClient := renovate.NewRenovateClient("") + queue := queue.NewGoQueue() + botHandler := bot.NewBotHandler(giteaClient) - cancelCtx, cancel := context.WithTimeout(ctx, time.Second*30) - defer cancel() + giteaWebhook := features.NewGiteaWebhook(botHandler, queue) - if err := renovateClient.RefreshRepository(cancelCtx, request.Owner, request.Repository); err != nil { - queue.Insert(MessageTypeRefreshRepositoryDone, RefreshDoneRepositoryRequest{ - Repository: request.Repository, - Owner: request.Owner, - PullRequestID: request.PullRequestID, - CommentID: request.CommentID, - CommentBody: request.CommentBody, - ReportProgress: request.ReportProgress, - Status: "failed", - Error: err.Error(), - }) - - return err - } - - queue.Insert(MessageTypeRefreshRepositoryDone, RefreshDoneRepositoryRequest{ - Repository: request.Repository, - Owner: request.Owner, - PullRequestID: request.PullRequestID, - CommentID: request.CommentID, - CommentBody: request.CommentBody, - ReportProgress: request.ReportProgress, - Status: "done", - Error: "", - }) - - return nil - }, - ) - - queue.Subscribe( - MessageTypeRefreshRepositoryDone, - func(ctx context.Context, item *QueueMessage) error { - var doneRequest RefreshDoneRepositoryRequest - if err := json.Unmarshal([]byte(item.Content), &doneRequest); err != nil { - log.Printf("failed to unmarshal request body: %s", err.Error()) - return err - } - - return giteaClient.EditComment(ctx, &doneRequest) - }, - ) + features.RegisterGiteaQueues(queue, renovateClient, giteaClient) cmd := &cobra.Command{ Use: "server", @@ -148,41 +68,15 @@ func serverCmd() *cobra.Command { cmd.PersistentFlags().StringVar(&url, "url", "", "the api url of the server") cmd.PersistentFlags().StringVar(&token, "token", "", "the token to authenticate with") - cmd.AddCommand(serverServeCmd(&url, &token, queue, giteaClient)) + cmd.AddCommand(serverServeCmd(&url, &token, giteaWebhook)) return cmd } -const ( - MessageTypeRefreshRepository = "refresh_repository" - MessageTypeRefreshRepositoryDone = "refresh_repository_done" -) - -type RefreshRepositoryRequest struct { - Repository string `json:"repository"` - Owner string `json:"owner"` - PullRequestID int `json:"pullRequestId"` - CommentID int `json:"commentId"` - CommentBody string `json:"commentBody"` - ReportProgress bool `json:"reportProgress"` -} - -type RefreshDoneRepositoryRequest struct { - Repository string `json:"repository"` - Owner string `json:"owner"` - PullRequestID int `json:"pullRequestId"` - CommentID int `json:"commentId"` - CommentBody string `json:"commentBody"` - ReportProgress bool `json:"reportProgress"` - Status string `json:"status"` - Error string `json:"error"` -} - func serverServeCmd( url *string, token *string, - queue *GoQueue, - giteaClient *GiteaClient, + giteaWebhook *features.GiteaWebhook, ) *cobra.Command { cmd := &cobra.Command{ Use: "serve", @@ -192,67 +86,19 @@ func serverServeCmd( gitea := engine.Group("/gitea") { gitea.POST("/webhook", func(ctx *gin.Context) { - log.Println("received") - - type GiteaWebhookRequest struct { - Action string `json:"action"` - Issue struct { - Id int `json:"id"` - Number int `json:"number"` - } `json:"issue"` - Comment struct { - Body string `json:"body"` - } `json:"comment"` - Repository struct { - FullName string `json:"full_name"` - } - } - - var request GiteaWebhookRequest + var request features.GiteaWebhookRequest if err := ctx.BindJSON(&request); err != nil { ctx.AbortWithError(500, err) return } - command, ok := validateBotComment(request.Comment.Body) - if ok { - log.Printf("got webhook request: contractor %s", command) - - bot := NewBotHandler(giteaClient) - output, err := bot.Handle(command) - if err != nil { - log.Printf("failed to run bot handler with error: %s", err.Error()) - } - - parts := strings.Split(request.Repository.FullName, "/") - - comment, err := bot.AppendComment( - parts[0], - parts[1], - request.Issue.Number, - output, - ) - if err != nil { - ctx.AbortWithError(500, err) - return - } - - if err := queue.Insert(MessageTypeRefreshRepository, RefreshRepositoryRequest{ - Repository: parts[1], - Owner: parts[0], - PullRequestID: request.Issue.Number, - CommentID: comment.ID, - CommentBody: comment.Body, - ReportProgress: true, - }); err != nil { - ctx.AbortWithError(500, err) - return - } - - ctx.Status(204) - + if err := giteaWebhook.HandleGiteaWebhook(ctx.Request.Context(), &request); err != nil { + ctx.AbortWithError(500, err) + return } + + ctx.Status(204) }) } @@ -263,14 +109,6 @@ func serverServeCmd( return cmd } -func validateBotComment(s string) (request string, ok bool) { - if after, ok := strings.CutPrefix(s, "/contractor"); ok { - return strings.TrimSpace(after), true - } - - return "", false -} - func RootCmd() *cobra.Command { cmd := &cobra.Command{Use: "contractor"} @@ -278,473 +116,3 @@ func RootCmd() *cobra.Command { return cmd } - -type BotHandler struct { - giteaClient *GiteaClient -} - -func NewBotHandler(gitea *GiteaClient) *BotHandler { - return &BotHandler{giteaClient: gitea} -} - -func (b *BotHandler) Handle(input string) (output string, err error) { - innerHandle := func(input string) (output string, err error) { - if strings.HasPrefix(input, "help") { - return b.Help(), nil - } - - if strings.HasPrefix(input, "refresh") { - return ` -

Contractor triggered renovate refresh on this repository

-This comment will be updated with status - - - -`, nil - } - - return b.Help(), errors.New("could not recognize command") - } - - output, err = innerHandle(input) - output = fmt.Sprintf( - "%s\nThis comment was generated by
Contractor", - output, - ) - return output, err -} - -func (b *BotHandler) Help() string { - return `
-

/contractor [command]

- -Commands: - -* /contractor help - * triggers the help menu -* /contractor refresh - * triggers renovate to refresh the current pull request -
` -} - -type AddCommentResponse struct { - Body string `json:"body"` - ID int `json:"id"` -} - -func (b *BotHandler) AppendComment( - owner string, - repository string, - pullRequest int, - comment string, -) (*AddCommentResponse, error) { - return b.giteaClient.AddComment(owner, repository, pullRequest, comment) -} - -type QueueMessage struct { - Type string `json:"type"` - Content string `json:"content"` -} - -type GoQueue struct { - queue []*QueueMessage - queueLock sync.Mutex - subscribers map[string]map[string]func(ctx context.Context, item *QueueMessage) error - subscribersLock sync.RWMutex -} - -func NewGoQueue() *GoQueue { - return &GoQueue{ - queue: make([]*QueueMessage, 0), - subscribers: make( - map[string]map[string]func(ctx context.Context, item *QueueMessage) error, - ), - } -} - -func (gq *GoQueue) Subscribe( - messageType string, - callback func(ctx context.Context, item *QueueMessage) error, -) string { - gq.subscribersLock.Lock() - defer gq.subscribersLock.Unlock() - - uid, err := uuid.NewUUID() - if err != nil { - panic(err) - } - id := uid.String() - - _, ok := gq.subscribers[messageType] - if !ok { - messageTypeSubscribers := make( - map[string]func(ctx context.Context, item *QueueMessage) error, - ) - messageTypeSubscribers[id] = callback - gq.subscribers[messageType] = messageTypeSubscribers - } else { - gq.subscribers[messageType][id] = callback - } - - return id -} - -func (gq *GoQueue) Unsubscribe(messageType string, id string) { - gq.subscribersLock.Lock() - defer gq.subscribersLock.Unlock() - _, ok := gq.subscribers[messageType] - if !ok { - // No work to be done - return - } else { - delete(gq.subscribers[messageType], id) - } -} - -func (gq *GoQueue) Insert(messageType string, content any) error { - gq.queueLock.Lock() - defer gq.queueLock.Unlock() - - contents, err := json.Marshal(content) - if err != nil { - return err - } - - gq.queue = append(gq.queue, &QueueMessage{ - Type: messageType, - Content: string(contents), - }) - - go func() { - gq.handle(context.Background()) - }() - - return nil -} - -func (gq *GoQueue) handle(ctx context.Context) { - gq.queueLock.Lock() - defer gq.queueLock.Unlock() - - for { - if len(gq.queue) == 0 { - return - } - - item := gq.queue[0] - gq.queue = gq.queue[1:] - - gq.subscribersLock.RLock() - defer gq.subscribersLock.RUnlock() - - for id, callback := range gq.subscribers[item.Type] { - log.Printf("sending message to %s", id) - go callback(ctx, item) - } - } -} - -type GiteaClient struct { - url *string - token *string - - client *http.Client -} - -func NewGiteaClient(url, token *string) *GiteaClient { - return &GiteaClient{ - url: url, - token: token, - client: http.DefaultClient, - } -} - -func (gc *GiteaClient) EditComment( - ctx context.Context, - doneRequest *RefreshDoneRepositoryRequest, -) error { - commentBody := html.UnescapeString(doneRequest.CommentBody) - startCmnt := "" - startIdx := strings.Index(commentBody, startCmnt) - endIdx := strings.Index(commentBody, "") - if startIdx >= 0 && endIdx >= 0 { - log.Println("found comment to replace") - - var content string - - if doneRequest.Error != "" { - content = fmt.Sprintf("
ERROR: %s

", doneRequest.Error) - } - if doneRequest.Status != "" { - content = fmt.Sprintf("

%s

", doneRequest.Status) - } - - doneRequest.CommentBody = fmt.Sprintf( - "%s

%s

%s", - commentBody[:startIdx+len(startCmnt)], - content, - commentBody[endIdx:], - ) - } - - editComment := struct { - Body string `json:"body"` - }{ - Body: doneRequest.CommentBody, - } - - body, err := json.Marshal(editComment) - if err != nil { - log.Println("failed to marshal request body: %w", err) - return err - } - bodyReader := bytes.NewReader(body) - - request, err := http.NewRequest( - http.MethodPatch, - fmt.Sprintf( - "%s/repos/%s/%s/issues/comments/%d", - strings.TrimSuffix(*gc.url, "/"), - doneRequest.Owner, - doneRequest.Repository, - doneRequest.CommentID, - ), - bodyReader, - ) - if err != nil { - log.Printf("failed to form update comment request: %s", err.Error()) - return err - } - request.Header.Add("Authorization", fmt.Sprintf("token %s", *gc.token)) - request.Header.Add("Content-Type", "application/json") - - resp, err := gc.client.Do(request) - if err != nil { - log.Printf("failed to update comment: %s", err.Error()) - return err - } - - if resp.StatusCode > 299 { - log.Printf("failed to update comment with status code: %d", resp.StatusCode) - respBody, err := io.ReadAll(resp.Body) - if err != nil { - log.Printf("failed to read body of error response: %s", err.Error()) - } else { - log.Printf("request body: %s", string(respBody)) - } - } - - return nil -} - -func (gc *GiteaClient) CreateWebhook(owner, repository string) error { - createHookOptions := createHook{ - Active: true, - AuthorizationHeader: "", - BranchFilter: "*", - Config: map[string]string{ - "url": "http://10.0.9.1:8080/gitea/webhook", - "content_type": "json", - }, - Events: []string{ - "pull_request_comment", - }, - Type: "gitea", - } - - body, err := json.Marshal(createHookOptions) - if err != nil { - log.Println("failed to marshal request body: %w", err) - return err - } - bodyReader := bytes.NewReader(body) - request, err := http.NewRequest( - http.MethodPost, - fmt.Sprintf( - "%s/repos/%s/%s/hooks", - strings.TrimSuffix(*gc.url, "/"), - owner, - repository, - ), - bodyReader, - ) - if err != nil { - log.Printf("failed to form create hook request: %s", err.Error()) - return err - } - request.Header.Add("Authorization", fmt.Sprintf("token %s", *gc.token)) - request.Header.Add("Content-Type", "application/json") - - resp, err := gc.client.Do(request) - if err != nil { - log.Printf("failed to register hook: %s", err.Error()) - return err - } - - if resp.StatusCode > 299 { - log.Printf("failed to register with status code: %d", resp.StatusCode) - respBody, err := io.ReadAll(resp.Body) - if err != nil { - log.Printf("failed to read body of error response: %s", err.Error()) - } else { - log.Printf("request body: %s", string(respBody)) - } - } - - return nil -} - -func (gc *GiteaClient) AddComment( - owner, repository string, - pullRequest int, - comment string, -) (*AddCommentResponse, error) { - addComment := struct { - Body string `json:"body"` - }{ - Body: comment, - } - - body, err := json.Marshal(addComment) - if err != nil { - return nil, err - } - bodyReader := bytes.NewReader(body) - - request, err := http.NewRequest( - http.MethodPost, - fmt.Sprintf( - "%s/repos/%s/%s/issues/%d/comments", - strings.TrimSuffix(*gc.url, "/"), - owner, - repository, - pullRequest, - ), - bodyReader, - ) - if err != nil { - return nil, err - } - request.Header.Add("Authorization", fmt.Sprintf("token %s", *gc.token)) - request.Header.Add("Content-Type", "application/json") - - resp, err := gc.client.Do(request) - if err != nil { - return nil, err - } - - if resp.StatusCode > 299 { - log.Printf("failed to register with status code: %d", resp.StatusCode) - respBody, err := io.ReadAll(resp.Body) - if err != nil { - return nil, err - } else { - log.Printf("request body: %s", string(respBody)) - } - } - - respBody, err := io.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - var response AddCommentResponse - if err := json.Unmarshal(respBody, &response); err != nil { - return nil, err - } - - return &response, nil -} - -type RenovateClient struct { - config string -} - -func NewRenovateClient(config string) *RenovateClient { - return &RenovateClient{config: config} -} - -func (rc *RenovateClient) RefreshRepository(ctx context.Context, owner, repository string) error { - client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stdout)) - if err != nil { - return err - } - - envRenovateToken := os.Getenv("GITEA_RENOVATE_TOKEN") - log.Println(envRenovateToken) - - renovateToken := client.SetSecret("RENOVATE_TOKEN", envRenovateToken) - githubComToken := client.SetSecret("GITHUB_COM_TOKEN", os.Getenv("GITHUB_COM_TOKEN")) - renovateSecret := client.SetSecret("RENOVATE_SECRETS", os.Getenv("RENOVATE_SECRETS")) - - output, err := client.Container(). - From("renovate/renovate:latest"). - WithNewFile("/opts/renovate/config.json", dagger.ContainerWithNewFileOpts{ - Contents: `{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "platform": "gitea", - "endpoint": "https://git.front.kjuulh.io/api/v1/", - "automerge": true, - "automergeType": "pr", - "extends": [ - "config:base" - ], - "hostRules": [ - { - "hostType": "docker", - "matchHost": "harbor.front.kjuulh.io", - "username": "service", - "password": "{{ secrets.HARBOR_SERVER_PASSWORD }}" - } - ], - "packageRules": [ - { - "matchDatasources": ["docker"], - "registryUrls": ["https://harbor.front.kjuulh.io/docker-proxy/library/"] - }, - { - "groupName": "all dependencies", - "separateMajorMinor": false, - "groupSlug": "all", - "packageRules": [ - { - "matchPackagePatterns": [ - "*" - ], - "groupName": "all dependencies", - "groupSlug": "all" - } - ], - "lockFileMaintenance": { - "enabled": false - } - } - ] -}`, - Permissions: 755, - Owner: "root", - }). - WithSecretVariable("RENOVATE_TOKEN", renovateToken). - WithSecretVariable("GITHUB_COM_TOKEN", githubComToken). - WithSecretVariable("RENOVATE_SECRETS", renovateSecret). - WithEnvVariable("LOG_LEVEL", "warn"). - WithEnvVariable("RENOVATE_CONFIG_FILE", "/opts/renovate/config.json"). - WithExec([]string{ - fmt.Sprintf("%s/%s", owner, repository), - }). - Sync(ctx) - - stdout, outerr := output.Stdout(ctx) - if outerr == nil { - log.Printf("stdout: %s", stdout) - } - stderr, outerr := output.Stderr(ctx) - if outerr == nil { - log.Printf("stderr: %s", stderr) - } - if err != nil { - return fmt.Errorf("error: %w, \nstderr: %s\nstdout: %s", err, stderr, stdout) - } - - return nil -} diff --git a/internal/bot/giteabot.go b/internal/bot/giteabot.go new file mode 100644 index 0000000..27ab20f --- /dev/null +++ b/internal/bot/giteabot.go @@ -0,0 +1,67 @@ +package bot + +import ( + "errors" + "fmt" + "strings" + + "git.front.kjuulh.io/kjuulh/contractor/internal/models" + "git.front.kjuulh.io/kjuulh/contractor/internal/providers" +) + +type BotHandler struct { + giteaClient *providers.GiteaClient +} + +func NewBotHandler(gitea *providers.GiteaClient) *BotHandler { + return &BotHandler{giteaClient: gitea} +} + +func (b *BotHandler) Handle(input string) (output string, err error) { + innerHandle := func(input string) (output string, err error) { + if strings.HasPrefix(input, "help") { + return b.Help(), nil + } + + if strings.HasPrefix(input, "refresh") { + return ` +

Contractor triggered renovate refresh on this repository

+This comment will be updated with status + + + +`, nil + } + + return b.Help(), errors.New("could not recognize command") + } + + output, err = innerHandle(input) + output = fmt.Sprintf( + "%s\nThis comment was generated by Contractor", + output, + ) + return output, err +} + +func (b *BotHandler) Help() string { + return `
+

/contractor [command]

+ +Commands: + +* /contractor help + * triggers the help menu +* /contractor refresh + * triggers renovate to refresh the current pull request +
` +} + +func (b *BotHandler) AppendComment( + owner string, + repository string, + pullRequest int, + comment string, +) (*models.AddCommentResponse, error) { + return b.giteaClient.AddComment(owner, repository, pullRequest, comment) +} diff --git a/internal/features/handle_gitea_events.go b/internal/features/handle_gitea_events.go new file mode 100644 index 0000000..1c312bf --- /dev/null +++ b/internal/features/handle_gitea_events.go @@ -0,0 +1,84 @@ +package features + +import ( + "context" + "encoding/json" + "log" + "time" + + "git.front.kjuulh.io/kjuulh/contractor/internal/models" + "git.front.kjuulh.io/kjuulh/contractor/internal/providers" + "git.front.kjuulh.io/kjuulh/contractor/internal/queue" + "git.front.kjuulh.io/kjuulh/contractor/internal/renovate" +) + +func RegisterGiteaQueues(goqueue *queue.GoQueue, renovate *renovate.RenovateClient, giteaClient *providers.GiteaClient) { + goqueue.Subscribe( + models.MessageTypeRefreshRepository, + func(ctx context.Context, item *queue.QueueMessage) error { + log.Printf("handling message: %s, content: %s", item.Type, item.Content) + return nil + }, + ) + goqueue.Subscribe( + models.MessageTypeRefreshRepositoryDone, + func(ctx context.Context, item *queue.QueueMessage) error { + log.Printf("handling message: %s, content: %s", item.Type, item.Content) + return nil + }, + ) + goqueue.Subscribe( + models.MessageTypeRefreshRepository, + func(ctx context.Context, item *queue.QueueMessage) error { + var request models.RefreshRepositoryRequest + if err := json.Unmarshal([]byte(item.Content), &request); err != nil { + log.Printf("failed to unmarshal request body: %s", err.Error()) + return err + } + + cancelCtx, cancel := context.WithTimeout(ctx, time.Minute*5) + defer cancel() + + if err := renovate.RefreshRepository(cancelCtx, request.Owner, request.Repository); err != nil { + goqueue.Insert(models.MessageTypeRefreshRepositoryDone, models.RefreshDoneRepositoryRequest{ + Repository: request.Repository, + Owner: request.Owner, + PullRequestID: request.PullRequestID, + CommentID: request.CommentID, + CommentBody: request.CommentBody, + ReportProgress: request.ReportProgress, + Status: "failed", + Error: err.Error(), + }) + + return err + } + + goqueue.Insert(models.MessageTypeRefreshRepositoryDone, models.RefreshDoneRepositoryRequest{ + Repository: request.Repository, + Owner: request.Owner, + PullRequestID: request.PullRequestID, + CommentID: request.CommentID, + CommentBody: request.CommentBody, + ReportProgress: request.ReportProgress, + Status: "done", + Error: "", + }) + + return nil + }, + ) + + goqueue.Subscribe( + models.MessageTypeRefreshRepositoryDone, + func(ctx context.Context, item *queue.QueueMessage) error { + var doneRequest models.RefreshDoneRepositoryRequest + if err := json.Unmarshal([]byte(item.Content), &doneRequest); err != nil { + log.Printf("failed to unmarshal request body: %s", err.Error()) + return err + } + + return giteaClient.EditComment(ctx, &doneRequest) + }, + ) +} diff --git a/internal/features/handle_gitea_webhook.go b/internal/features/handle_gitea_webhook.go new file mode 100644 index 0000000..d7a7490 --- /dev/null +++ b/internal/features/handle_gitea_webhook.go @@ -0,0 +1,83 @@ +package features + +import ( + "context" + "log" + "strings" + + "git.front.kjuulh.io/kjuulh/contractor/internal/bot" + "git.front.kjuulh.io/kjuulh/contractor/internal/models" + "git.front.kjuulh.io/kjuulh/contractor/internal/queue" +) + +type GiteaWebhook struct { + botHandler *bot.BotHandler + queue *queue.GoQueue +} + +type GiteaWebhookRequest struct { + Action string `json:"action"` + Issue struct { + Id int `json:"id"` + Number int `json:"number"` + } `json:"issue"` + Comment struct { + Body string `json:"body"` + } `json:"comment"` + Repository struct { + FullName string `json:"full_name"` + } +} + +func NewGiteaWebhook(botHandler *bot.BotHandler, queue *queue.GoQueue) *GiteaWebhook { + return &GiteaWebhook{ + botHandler: botHandler, + queue: queue, + } +} + +func (gw *GiteaWebhook) HandleGiteaWebhook(ctx context.Context, request *GiteaWebhookRequest) error { + command, ok := validateBotComment(request.Comment.Body) + if ok { + log.Printf("got webhook request: contractor %s", command) + + bot := gw.botHandler + output, err := bot.Handle(command) + if err != nil { + log.Printf("failed to run bot handler with error: %s", err.Error()) + } + + parts := strings.Split(request.Repository.FullName, "/") + + comment, err := bot.AppendComment( + parts[0], + parts[1], + request.Issue.Number, + output, + ) + if err != nil { + return err + } + + if err := gw.queue.Insert(models.MessageTypeRefreshRepository, models.RefreshRepositoryRequest{ + Repository: parts[1], + Owner: parts[0], + PullRequestID: request.Issue.Number, + CommentID: comment.ID, + CommentBody: comment.Body, + ReportProgress: true, + }); err != nil { + return err + } + } + + return nil +} + +func validateBotComment(s string) (request string, ok bool) { + if after, ok := strings.CutPrefix(s, "/contractor"); ok { + return strings.TrimSpace(after), true + } + + return "", false +} diff --git a/internal/models/requests.go b/internal/models/requests.go new file mode 100644 index 0000000..392aed0 --- /dev/null +++ b/internal/models/requests.go @@ -0,0 +1,40 @@ +package models + +const ( + MessageTypeRefreshRepository = "refresh_repository" + MessageTypeRefreshRepositoryDone = "refresh_repository_done" +) + +type CreateHook struct { + Active bool `json:"active"` + AuthorizationHeader string `json:"authorization_header"` + BranchFilter string `json:"branch_filter"` + Config map[string]string `json:"config"` + Events []string `json:"events"` + Type string `json:"type"` +} + +type RefreshRepositoryRequest struct { + Repository string `json:"repository"` + Owner string `json:"owner"` + PullRequestID int `json:"pullRequestId"` + CommentID int `json:"commentId"` + CommentBody string `json:"commentBody"` + ReportProgress bool `json:"reportProgress"` +} + +type RefreshDoneRepositoryRequest struct { + Repository string `json:"repository"` + Owner string `json:"owner"` + PullRequestID int `json:"pullRequestId"` + CommentID int `json:"commentId"` + CommentBody string `json:"commentBody"` + ReportProgress bool `json:"reportProgress"` + Status string `json:"status"` + Error string `json:"error"` +} + +type AddCommentResponse struct { + Body string `json:"body"` + ID int `json:"id"` +} diff --git a/internal/providers/gitea.go b/internal/providers/gitea.go new file mode 100644 index 0000000..2851198 --- /dev/null +++ b/internal/providers/gitea.go @@ -0,0 +1,227 @@ +package providers + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "html" + "io" + "log" + "net/http" + "strings" + + "git.front.kjuulh.io/kjuulh/contractor/internal/models" +) + +type GiteaClient struct { + url *string + token *string + + client *http.Client +} + +func NewGiteaClient(url, token *string) *GiteaClient { + return &GiteaClient{ + url: url, + token: token, + client: http.DefaultClient, + } +} + +func (gc *GiteaClient) EditComment( + ctx context.Context, + doneRequest *models.RefreshDoneRepositoryRequest, +) error { + commentBody := html.UnescapeString(doneRequest.CommentBody) + startCmnt := "" + startIdx := strings.Index(commentBody, startCmnt) + endIdx := strings.Index(commentBody, "") + if startIdx >= 0 && endIdx >= 0 { + log.Println("found comment to replace") + + var content string + + if doneRequest.Error != "" { + content = fmt.Sprintf("
ERROR: %s

", doneRequest.Error) + } + if doneRequest.Status != "" { + content = fmt.Sprintf("%s

%s

", content, doneRequest.Status) + } + + doneRequest.CommentBody = fmt.Sprintf( + "%s

%s

%s", + commentBody[:startIdx+len(startCmnt)], + content, + commentBody[endIdx:], + ) + } + + editComment := struct { + Body string `json:"body"` + }{ + Body: doneRequest.CommentBody, + } + + body, err := json.Marshal(editComment) + if err != nil { + log.Println("failed to marshal request body: %w", err) + return err + } + bodyReader := bytes.NewReader(body) + + request, err := http.NewRequest( + http.MethodPatch, + fmt.Sprintf( + "%s/repos/%s/%s/issues/comments/%d", + strings.TrimSuffix(*gc.url, "/"), + doneRequest.Owner, + doneRequest.Repository, + doneRequest.CommentID, + ), + bodyReader, + ) + if err != nil { + log.Printf("failed to form update comment request: %s", err.Error()) + return err + } + request.Header.Add("Authorization", fmt.Sprintf("token %s", *gc.token)) + request.Header.Add("Content-Type", "application/json") + + resp, err := gc.client.Do(request) + if err != nil { + log.Printf("failed to update comment: %s", err.Error()) + return err + } + + if resp.StatusCode > 299 { + log.Printf("failed to update comment with status code: %d", resp.StatusCode) + respBody, err := io.ReadAll(resp.Body) + if err != nil { + log.Printf("failed to read body of error response: %s", err.Error()) + } else { + log.Printf("request body: %s", string(respBody)) + } + } + + return nil +} + +func (gc *GiteaClient) CreateWebhook(owner, repository string) error { + createHookOptions := models.CreateHook{ + Active: true, + AuthorizationHeader: "", + BranchFilter: "*", + Config: map[string]string{ + "url": "http://10.0.9.1:8080/gitea/webhook", + "content_type": "json", + }, + Events: []string{ + "pull_request_comment", + }, + Type: "gitea", + } + + body, err := json.Marshal(createHookOptions) + if err != nil { + log.Println("failed to marshal request body: %w", err) + return err + } + bodyReader := bytes.NewReader(body) + request, err := http.NewRequest( + http.MethodPost, + fmt.Sprintf( + "%s/repos/%s/%s/hooks", + strings.TrimSuffix(*gc.url, "/"), + owner, + repository, + ), + bodyReader, + ) + if err != nil { + log.Printf("failed to form create hook request: %s", err.Error()) + return err + } + request.Header.Add("Authorization", fmt.Sprintf("token %s", *gc.token)) + request.Header.Add("Content-Type", "application/json") + + resp, err := gc.client.Do(request) + if err != nil { + log.Printf("failed to register hook: %s", err.Error()) + return err + } + + if resp.StatusCode > 299 { + log.Printf("failed to register with status code: %d", resp.StatusCode) + respBody, err := io.ReadAll(resp.Body) + if err != nil { + log.Printf("failed to read body of error response: %s", err.Error()) + } else { + log.Printf("request body: %s", string(respBody)) + } + } + + return nil +} + +func (gc *GiteaClient) AddComment( + owner, repository string, + pullRequest int, + comment string, +) (*models.AddCommentResponse, error) { + addComment := struct { + Body string `json:"body"` + }{ + Body: comment, + } + + body, err := json.Marshal(addComment) + if err != nil { + return nil, err + } + bodyReader := bytes.NewReader(body) + + request, err := http.NewRequest( + http.MethodPost, + fmt.Sprintf( + "%s/repos/%s/%s/issues/%d/comments", + strings.TrimSuffix(*gc.url, "/"), + owner, + repository, + pullRequest, + ), + bodyReader, + ) + if err != nil { + return nil, err + } + request.Header.Add("Authorization", fmt.Sprintf("token %s", *gc.token)) + request.Header.Add("Content-Type", "application/json") + + resp, err := gc.client.Do(request) + if err != nil { + return nil, err + } + + if resp.StatusCode > 299 { + log.Printf("failed to register with status code: %d", resp.StatusCode) + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } else { + log.Printf("request body: %s", string(respBody)) + } + } + + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + var response models.AddCommentResponse + if err := json.Unmarshal(respBody, &response); err != nil { + return nil, err + } + + return &response, nil +} diff --git a/internal/queue/goqueue.go b/internal/queue/goqueue.go new file mode 100644 index 0000000..13b863c --- /dev/null +++ b/internal/queue/goqueue.go @@ -0,0 +1,113 @@ +package queue + +import ( + "context" + "encoding/json" + "log" + "sync" + + "github.com/google/uuid" +) + +type QueueMessage struct { + Type string `json:"type"` + Content string `json:"content"` +} + +type GoQueue struct { + queue []*QueueMessage + queueLock sync.Mutex + subscribers map[string]map[string]func(ctx context.Context, item *QueueMessage) error + subscribersLock sync.RWMutex +} + +func NewGoQueue() *GoQueue { + return &GoQueue{ + queue: make([]*QueueMessage, 0), + subscribers: make( + map[string]map[string]func(ctx context.Context, item *QueueMessage) error, + ), + } +} + +func (gq *GoQueue) Subscribe( + messageType string, + callback func(ctx context.Context, item *QueueMessage) error, +) string { + gq.subscribersLock.Lock() + defer gq.subscribersLock.Unlock() + + uid, err := uuid.NewUUID() + if err != nil { + panic(err) + } + id := uid.String() + + _, ok := gq.subscribers[messageType] + if !ok { + messageTypeSubscribers := make( + map[string]func(ctx context.Context, item *QueueMessage) error, + ) + messageTypeSubscribers[id] = callback + gq.subscribers[messageType] = messageTypeSubscribers + } else { + gq.subscribers[messageType][id] = callback + } + + return id +} + +func (gq *GoQueue) Unsubscribe(messageType string, id string) { + gq.subscribersLock.Lock() + defer gq.subscribersLock.Unlock() + _, ok := gq.subscribers[messageType] + if !ok { + // No work to be done + return + } else { + delete(gq.subscribers[messageType], id) + } +} + +func (gq *GoQueue) Insert(messageType string, content any) error { + gq.queueLock.Lock() + defer gq.queueLock.Unlock() + + contents, err := json.Marshal(content) + if err != nil { + return err + } + + gq.queue = append(gq.queue, &QueueMessage{ + Type: messageType, + Content: string(contents), + }) + + go func() { + gq.handle(context.Background()) + }() + + return nil +} + +func (gq *GoQueue) handle(ctx context.Context) { + gq.queueLock.Lock() + defer gq.queueLock.Unlock() + + for { + if len(gq.queue) == 0 { + return + } + + item := gq.queue[0] + gq.queue = gq.queue[1:] + + gq.subscribersLock.RLock() + defer gq.subscribersLock.RUnlock() + + for id, callback := range gq.subscribers[item.Type] { + log.Printf("sending message to %s", id) + go callback(ctx, item) + } + } +} diff --git a/internal/renovate/client.go b/internal/renovate/client.go new file mode 100644 index 0000000..f0db6bd --- /dev/null +++ b/internal/renovate/client.go @@ -0,0 +1,103 @@ +package renovate + +import ( + "context" + "fmt" + "log" + "os" + + "dagger.io/dagger" +) + +type RenovateClient struct { + config string +} + +func NewRenovateClient(config string) *RenovateClient { + return &RenovateClient{config: config} +} + +func (rc *RenovateClient) RefreshRepository(ctx context.Context, owner, repository string) error { + client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stdout)) + if err != nil { + return err + } + + envRenovateToken := os.Getenv("GITEA_RENOVATE_TOKEN") + log.Println(envRenovateToken) + + renovateToken := client.SetSecret("RENOVATE_TOKEN", envRenovateToken) + githubComToken := client.SetSecret("GITHUB_COM_TOKEN", os.Getenv("GITHUB_COM_TOKEN")) + renovateSecret := client.SetSecret("RENOVATE_SECRETS", os.Getenv("RENOVATE_SECRETS")) + + output, err := client.Container(). + From("renovate/renovate:latest"). + WithNewFile("/opts/renovate/config.json", dagger.ContainerWithNewFileOpts{ + Contents: `{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "platform": "gitea", + "endpoint": "https://git.front.kjuulh.io/api/v1/", + "automerge": true, + "automergeType": "pr", + "extends": [ + "config:base" + ], + "hostRules": [ + { + "hostType": "docker", + "matchHost": "harbor.front.kjuulh.io", + "username": "service", + "password": "{{ secrets.HARBOR_SERVER_PASSWORD }}" + } + ], + "packageRules": [ + { + "matchDatasources": ["docker"], + "registryUrls": ["https://harbor.front.kjuulh.io/docker-proxy/library/"] + }, + { + "groupName": "all dependencies", + "separateMajorMinor": false, + "groupSlug": "all", + "packageRules": [ + { + "matchPackagePatterns": [ + "*" + ], + "groupName": "all dependencies", + "groupSlug": "all" + } + ], + "lockFileMaintenance": { + "enabled": false + } + } + ] +}`, + Permissions: 755, + Owner: "root", + }). + WithSecretVariable("RENOVATE_TOKEN", renovateToken). + WithSecretVariable("GITHUB_COM_TOKEN", githubComToken). + WithSecretVariable("RENOVATE_SECRETS", renovateSecret). + WithEnvVariable("LOG_LEVEL", "warn"). + WithEnvVariable("RENOVATE_CONFIG_FILE", "/opts/renovate/config.json"). + WithExec([]string{ + fmt.Sprintf("%s/%s", owner, repository), + }). + Sync(ctx) + + stdout, outerr := output.Stdout(ctx) + if outerr == nil { + log.Printf("stdout: %s", stdout) + } + stderr, outerr := output.Stderr(ctx) + if outerr == nil { + log.Printf("stderr: %s", stderr) + } + if err != nil { + return fmt.Errorf("error: %w, \nstderr: %s\nstdout: %s", err, stderr, stdout) + } + + return nil +} -- 2.45.2 From 89c1c72d8722bf608344a27c08b1dee25c7ee98e Mon Sep 17 00:00:00 2001 From: kjuulh Date: Wed, 9 Aug 2023 15:44:31 +0200 Subject: [PATCH 15/74] feat(github): add github support Signed-off-by: kjuulh --- cmd/contractor/main.go | 37 ++++++- go.mod | 9 ++ go.sum | 78 +++++++++++++- internal/bot/giteabot.go | 17 ++- internal/features/handle_gitea_events.go | 16 +-- internal/features/handle_gitea_webhook.go | 3 +- internal/features/handle_github_events.go | 84 +++++++++++++++ internal/features/handle_github_webhook.go | 76 +++++++++++++ internal/models/requests.go | 37 ++++++- internal/providers/gitea.go | 2 +- internal/providers/github.go | 117 +++++++++++++++++++++ 11 files changed, 452 insertions(+), 24 deletions(-) create mode 100644 internal/features/handle_github_events.go create mode 100644 internal/features/handle_github_webhook.go create mode 100644 internal/providers/github.go diff --git a/cmd/contractor/main.go b/cmd/contractor/main.go index 792a690..918bb77 100644 --- a/cmd/contractor/main.go +++ b/cmd/contractor/main.go @@ -50,16 +50,23 @@ func serverCmd() *cobra.Command { var ( url string token string + + githubAppID int64 + githubInstallationID int64 + githubPrivateKeyPath string ) giteaClient := providers.NewGiteaClient(&url, &token) + githubClient := providers.NewGitHubClient(&githubAppID, &githubInstallationID, &githubPrivateKeyPath) renovateClient := renovate.NewRenovateClient("") queue := queue.NewGoQueue() - botHandler := bot.NewBotHandler(giteaClient) + botHandler := bot.NewBotHandler(giteaClient, githubClient) giteaWebhook := features.NewGiteaWebhook(botHandler, queue) + githubWebhook := features.NewGitHubWebhook(botHandler, queue) features.RegisterGiteaQueues(queue, renovateClient, giteaClient) + features.RegisterGitHubQueues(queue, renovateClient, githubClient) cmd := &cobra.Command{ Use: "server", @@ -68,7 +75,11 @@ func serverCmd() *cobra.Command { cmd.PersistentFlags().StringVar(&url, "url", "", "the api url of the server") cmd.PersistentFlags().StringVar(&token, "token", "", "the token to authenticate with") - cmd.AddCommand(serverServeCmd(&url, &token, giteaWebhook)) + cmd.PersistentFlags().Int64Var(&githubAppID, "github-app-id", 0, "github app id to authenticate with") + cmd.PersistentFlags().Int64Var(&githubInstallationID, "github-installation-id", 0, "github installation id to authenticate with") + cmd.PersistentFlags().StringVar(&githubPrivateKeyPath, "github-private-key-path", "", "path to the github app private key") + + cmd.AddCommand(serverServeCmd(&url, &token, giteaWebhook, githubWebhook)) return cmd } @@ -77,16 +88,34 @@ func serverServeCmd( url *string, token *string, giteaWebhook *features.GiteaWebhook, + githubWebhook *features.GitHubWebhook, ) *cobra.Command { cmd := &cobra.Command{ Use: "serve", Run: func(cmd *cobra.Command, args []string) { engine := gin.Default() + github := engine.Group("/github") + { + github.POST("/webhook", func(ctx *gin.Context) { + var request features.GitHubWebhookRequest + if err := ctx.BindJSON(&request); err != nil { + ctx.AbortWithError(500, err) + return + } + + if err := githubWebhook.HandleGitHubWebhook(ctx.Request.Context(), &request); err != nil { + ctx.AbortWithError(500, err) + return + } + + ctx.Status(204) + }) + } + gitea := engine.Group("/gitea") { gitea.POST("/webhook", func(ctx *gin.Context) { - var request features.GiteaWebhookRequest if err := ctx.BindJSON(&request); err != nil { ctx.AbortWithError(500, err) @@ -102,7 +131,7 @@ func serverServeCmd( }) } - engine.Run("0.0.0.0:8080") + engine.Run("0.0.0.0:9111") }, } diff --git a/go.mod b/go.mod index eb76840..5f9fd8e 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.20 require ( dagger.io/dagger v0.8.1 github.com/gin-gonic/gin v1.9.1 + github.com/google/go-github/v53 v53.2.0 github.com/google/uuid v1.3.0 github.com/joho/godotenv v1.5.1 github.com/spf13/cobra v1.7.0 @@ -13,15 +14,21 @@ require ( require ( github.com/99designs/gqlgen v0.17.31 // indirect github.com/Khan/genqlient v0.6.0 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect github.com/adrg/xdg v0.4.0 // indirect + github.com/bradleyfalzon/ghinstallation/v2 v2.6.0 // indirect github.com/bytedance/sonic v1.9.1 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/cloudflare/circl v1.3.3 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.14.0 // indirect github.com/goccy/go-json v0.10.2 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/go-querystring v1.1.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -39,10 +46,12 @@ require ( golang.org/x/crypto v0.11.0 // indirect golang.org/x/mod v0.12.0 // indirect golang.org/x/net v0.12.0 // indirect + golang.org/x/oauth2 v0.8.0 // indirect golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.10.0 // indirect golang.org/x/text v0.11.0 // indirect golang.org/x/tools v0.11.0 // indirect + google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 4a41eac..e78dc17 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,12 @@ +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= dagger.io/dagger v0.8.1 h1:jLNPGubxrLWUfsX+snjaw913B1lxVmWftzdVehB+RQU= dagger.io/dagger v0.8.1/go.mod h1:CZwYt0FfVsEEYTFytzf2ihESB2P4H1S3/UfnrVxjBsE= github.com/99designs/gqlgen v0.17.31 h1:VncSQ82VxieHkea8tz11p7h/zSbvHSxSDZfywqWt158= github.com/99designs/gqlgen v0.17.31/go.mod h1:i4rEatMrzzu6RXaHydq1nmEPZkb3bKQsnxNRHS4DQB4= github.com/Khan/genqlient v0.6.0 h1:Bwb1170ekuNIVIwTJEqvO8y7RxBxXu639VJOkKSrwAk= github.com/Khan/genqlient v0.6.0/go.mod h1:rvChwWVTqXhiapdhLDV4bp9tz/Xvtewwkon4DpWWCRM= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= @@ -11,12 +14,19 @@ github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVb github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= +github.com/bradleyfalzon/ghinstallation/v2 v2.6.0 h1:IRY7Xy588KylkoycsUhFpW7cdGpy5Y5BPsz4IfuJtGk= +github.com/bradleyfalzon/ghinstallation/v2 v2.6.0/go.mod h1:oQ3etOwN3TRH4EwgW5/7MxSVMGlMlzG/O8TU7eYdoSk= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= +github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -37,9 +47,21 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github/v53 v53.2.0 h1:wvz3FyF53v4BK+AsnvCmeNhf8AkTaeh2SoYu/XUvTtI= +github.com/google/go-github/v53 v53.2.0/go.mod h1:XhFRObz+m/l+UCm9b7KSIC3lT3NWSXGt7mOsAWEloao= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -97,29 +119,81 @@ github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4d github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/vektah/gqlparser/v2 v2.5.6 h1:Ou14T0N1s191eRMZ1gARVqohcbe1e8FrcONScsq8cRU= github.com/vektah/gqlparser/v2 v2.5.6/go.mod h1:z8xXUff237NntSuH8mLFijZ+1tjV1swDbpDqjJmk6ME= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 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.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/bot/giteabot.go b/internal/bot/giteabot.go index 27ab20f..ea43e85 100644 --- a/internal/bot/giteabot.go +++ b/internal/bot/giteabot.go @@ -10,11 +10,12 @@ import ( ) type BotHandler struct { - giteaClient *providers.GiteaClient + giteaClient *providers.GiteaClient + githubClient *providers.GitHubClient } -func NewBotHandler(gitea *providers.GiteaClient) *BotHandler { - return &BotHandler{giteaClient: gitea} +func NewBotHandler(gitea *providers.GiteaClient, github *providers.GitHubClient) *BotHandler { + return &BotHandler{giteaClient: gitea, githubClient: github} } func (b *BotHandler) Handle(input string) (output string, err error) { @@ -62,6 +63,14 @@ func (b *BotHandler) AppendComment( repository string, pullRequest int, comment string, + backend models.SupportedBackend, ) (*models.AddCommentResponse, error) { - return b.giteaClient.AddComment(owner, repository, pullRequest, comment) + switch backend { + case models.SupportedBackendGitHub: + return b.githubClient.AddComment(owner, repository, pullRequest, comment) + case models.SupportedBackendGitea: + return b.giteaClient.AddComment(owner, repository, pullRequest, comment) + default: + panic("backend chosen was not a valid option") + } } diff --git a/internal/features/handle_gitea_events.go b/internal/features/handle_gitea_events.go index 1c312bf..c9b3567 100644 --- a/internal/features/handle_gitea_events.go +++ b/internal/features/handle_gitea_events.go @@ -14,23 +14,23 @@ import ( func RegisterGiteaQueues(goqueue *queue.GoQueue, renovate *renovate.RenovateClient, giteaClient *providers.GiteaClient) { goqueue.Subscribe( - models.MessageTypeRefreshRepository, + models.MessageTypeRefreshGiteaRepository, func(ctx context.Context, item *queue.QueueMessage) error { log.Printf("handling message: %s, content: %s", item.Type, item.Content) return nil }, ) goqueue.Subscribe( - models.MessageTypeRefreshRepositoryDone, + models.MessageTypeRefreshGiteaRepositoryDone, func(ctx context.Context, item *queue.QueueMessage) error { log.Printf("handling message: %s, content: %s", item.Type, item.Content) return nil }, ) goqueue.Subscribe( - models.MessageTypeRefreshRepository, + models.MessageTypeRefreshGiteaRepository, func(ctx context.Context, item *queue.QueueMessage) error { - var request models.RefreshRepositoryRequest + var request models.RefreshGiteaRepositoryRequest if err := json.Unmarshal([]byte(item.Content), &request); err != nil { log.Printf("failed to unmarshal request body: %s", err.Error()) return err @@ -40,7 +40,7 @@ func RegisterGiteaQueues(goqueue *queue.GoQueue, renovate *renovate.RenovateClie defer cancel() if err := renovate.RefreshRepository(cancelCtx, request.Owner, request.Repository); err != nil { - goqueue.Insert(models.MessageTypeRefreshRepositoryDone, models.RefreshDoneRepositoryRequest{ + goqueue.Insert(models.MessageTypeRefreshGiteaRepositoryDone, models.RefreshGiteaRepositoryDoneRequest{ Repository: request.Repository, Owner: request.Owner, PullRequestID: request.PullRequestID, @@ -54,7 +54,7 @@ func RegisterGiteaQueues(goqueue *queue.GoQueue, renovate *renovate.RenovateClie return err } - goqueue.Insert(models.MessageTypeRefreshRepositoryDone, models.RefreshDoneRepositoryRequest{ + goqueue.Insert(models.MessageTypeRefreshGiteaRepositoryDone, models.RefreshGiteaRepositoryDoneRequest{ Repository: request.Repository, Owner: request.Owner, PullRequestID: request.PullRequestID, @@ -70,9 +70,9 @@ func RegisterGiteaQueues(goqueue *queue.GoQueue, renovate *renovate.RenovateClie ) goqueue.Subscribe( - models.MessageTypeRefreshRepositoryDone, + models.MessageTypeRefreshGiteaRepositoryDone, func(ctx context.Context, item *queue.QueueMessage) error { - var doneRequest models.RefreshDoneRepositoryRequest + var doneRequest models.RefreshGiteaRepositoryDoneRequest if err := json.Unmarshal([]byte(item.Content), &doneRequest); err != nil { log.Printf("failed to unmarshal request body: %s", err.Error()) return err diff --git a/internal/features/handle_gitea_webhook.go b/internal/features/handle_gitea_webhook.go index d7a7490..48eaf9e 100644 --- a/internal/features/handle_gitea_webhook.go +++ b/internal/features/handle_gitea_webhook.go @@ -54,12 +54,13 @@ func (gw *GiteaWebhook) HandleGiteaWebhook(ctx context.Context, request *GiteaWe parts[1], request.Issue.Number, output, + models.SupportedBackendGitea, ) if err != nil { return err } - if err := gw.queue.Insert(models.MessageTypeRefreshRepository, models.RefreshRepositoryRequest{ + if err := gw.queue.Insert(models.MessageTypeRefreshGiteaRepository, models.RefreshGiteaRepositoryRequest{ Repository: parts[1], Owner: parts[0], PullRequestID: request.Issue.Number, diff --git a/internal/features/handle_github_events.go b/internal/features/handle_github_events.go new file mode 100644 index 0000000..8c8bea0 --- /dev/null +++ b/internal/features/handle_github_events.go @@ -0,0 +1,84 @@ +package features + +import ( + "context" + "encoding/json" + "log" + "time" + + "git.front.kjuulh.io/kjuulh/contractor/internal/models" + "git.front.kjuulh.io/kjuulh/contractor/internal/providers" + "git.front.kjuulh.io/kjuulh/contractor/internal/queue" + "git.front.kjuulh.io/kjuulh/contractor/internal/renovate" +) + +func RegisterGitHubQueues(goqueue *queue.GoQueue, renovate *renovate.RenovateClient, giteaClient *providers.GitHubClient) { + goqueue.Subscribe( + models.MessageTypeRefreshGitHubRepository, + func(ctx context.Context, item *queue.QueueMessage) error { + log.Printf("handling message: %s, content: %s", item.Type, item.Content) + return nil + }, + ) + goqueue.Subscribe( + models.MessageTypeRefreshGitHubRepositoryDone, + func(ctx context.Context, item *queue.QueueMessage) error { + log.Printf("handling message: %s, content: %s", item.Type, item.Content) + return nil + }, + ) + goqueue.Subscribe( + models.MessageTypeRefreshGitHubRepository, + func(ctx context.Context, item *queue.QueueMessage) error { + var request models.RefreshGitHubRepositoryRequest + if err := json.Unmarshal([]byte(item.Content), &request); err != nil { + log.Printf("failed to unmarshal request body: %s", err.Error()) + return err + } + + cancelCtx, cancel := context.WithTimeout(ctx, time.Minute*5) + defer cancel() + + if err := renovate.RefreshRepository(cancelCtx, request.Owner, request.Repository); err != nil { + goqueue.Insert(models.MessageTypeRefreshGitHubRepositoryDone, models.RefreshGitHubRepositoryDoneRequest{ + Repository: request.Repository, + Owner: request.Owner, + PullRequestID: request.PullRequestID, + CommentID: request.CommentID, + CommentBody: request.CommentBody, + ReportProgress: request.ReportProgress, + Status: "failed", + Error: err.Error(), + }) + + return err + } + + goqueue.Insert(models.MessageTypeRefreshGitHubRepositoryDone, models.RefreshGitHubRepositoryDoneRequest{ + Repository: request.Repository, + Owner: request.Owner, + PullRequestID: request.PullRequestID, + CommentID: request.CommentID, + CommentBody: request.CommentBody, + ReportProgress: request.ReportProgress, + Status: "done", + Error: "", + }) + + return nil + }, + ) + + goqueue.Subscribe( + models.MessageTypeRefreshGitHubRepositoryDone, + func(ctx context.Context, item *queue.QueueMessage) error { + var doneRequest models.RefreshGitHubRepositoryDoneRequest + if err := json.Unmarshal([]byte(item.Content), &doneRequest); err != nil { + log.Printf("failed to unmarshal request body: %s", err.Error()) + return err + } + + return giteaClient.EditComment(ctx, &doneRequest) + }, + ) +} diff --git a/internal/features/handle_github_webhook.go b/internal/features/handle_github_webhook.go new file mode 100644 index 0000000..42fab83 --- /dev/null +++ b/internal/features/handle_github_webhook.go @@ -0,0 +1,76 @@ +package features + +import ( + "context" + "log" + "strings" + + "git.front.kjuulh.io/kjuulh/contractor/internal/bot" + "git.front.kjuulh.io/kjuulh/contractor/internal/models" + "git.front.kjuulh.io/kjuulh/contractor/internal/queue" +) + +type GitHubWebhook struct { + botHandler *bot.BotHandler + queue *queue.GoQueue +} + +type GitHubWebhookRequest struct { + Action string `json:"action"` + Issue struct { + Id int `json:"id"` + Number int `json:"number"` + } `json:"issue"` + Comment struct { + Body string `json:"body"` + } `json:"comment"` + Repository struct { + FullName string `json:"full_name"` + } +} + +func NewGitHubWebhook(botHandler *bot.BotHandler, queue *queue.GoQueue) *GitHubWebhook { + return &GitHubWebhook{ + botHandler: botHandler, + queue: queue, + } +} + +func (gw *GitHubWebhook) HandleGitHubWebhook(ctx context.Context, request *GitHubWebhookRequest) error { + command, ok := validateBotComment(request.Comment.Body) + if ok { + log.Printf("got webhook request: contractor %s", command) + + bot := gw.botHandler + output, err := bot.Handle(command) + if err != nil { + log.Printf("failed to run bot handler with error: %s", err.Error()) + } + + parts := strings.Split(request.Repository.FullName, "/") + + comment, err := bot.AppendComment( + parts[0], + parts[1], + request.Issue.Number, + output, + models.SupportedBackendGitHub, + ) + if err != nil { + return err + } + + if err := gw.queue.Insert(models.MessageTypeRefreshGitHubRepository, models.RefreshGitHubRepositoryRequest{ + Repository: parts[1], + Owner: parts[0], + PullRequestID: request.Issue.Number, + CommentID: comment.ID, + CommentBody: comment.Body, + ReportProgress: true, + }); err != nil { + return err + } + } + + return nil +} diff --git a/internal/models/requests.go b/internal/models/requests.go index 392aed0..6716c8a 100644 --- a/internal/models/requests.go +++ b/internal/models/requests.go @@ -1,8 +1,10 @@ package models const ( - MessageTypeRefreshRepository = "refresh_repository" - MessageTypeRefreshRepositoryDone = "refresh_repository_done" + MessageTypeRefreshGiteaRepository = "refresh_gitea_repository" + MessageTypeRefreshGiteaRepositoryDone = "refresh_gitea_repository_done" + MessageTypeRefreshGitHubRepository = "refresh_github_repository" + MessageTypeRefreshGitHubRepositoryDone = "refresh_github_repository_done" ) type CreateHook struct { @@ -14,7 +16,7 @@ type CreateHook struct { Type string `json:"type"` } -type RefreshRepositoryRequest struct { +type RefreshGiteaRepositoryRequest struct { Repository string `json:"repository"` Owner string `json:"owner"` PullRequestID int `json:"pullRequestId"` @@ -23,7 +25,27 @@ type RefreshRepositoryRequest struct { ReportProgress bool `json:"reportProgress"` } -type RefreshDoneRepositoryRequest struct { +type RefreshGiteaRepositoryDoneRequest struct { + Repository string `json:"repository"` + Owner string `json:"owner"` + PullRequestID int `json:"pullRequestId"` + CommentID int `json:"commentId"` + CommentBody string `json:"commentBody"` + ReportProgress bool `json:"reportProgress"` + Status string `json:"status"` + Error string `json:"error"` +} + +type RefreshGitHubRepositoryRequest struct { + Repository string `json:"repository"` + Owner string `json:"owner"` + PullRequestID int `json:"pullRequestId"` + CommentID int `json:"commentId"` + CommentBody string `json:"commentBody"` + ReportProgress bool `json:"reportProgress"` +} + +type RefreshGitHubRepositoryDoneRequest struct { Repository string `json:"repository"` Owner string `json:"owner"` PullRequestID int `json:"pullRequestId"` @@ -38,3 +60,10 @@ type AddCommentResponse struct { Body string `json:"body"` ID int `json:"id"` } + +type SupportedBackend string + +const ( + SupportedBackendGitHub SupportedBackend = "github" + SupportedBackendGitea SupportedBackend = "gitea" +) diff --git a/internal/providers/gitea.go b/internal/providers/gitea.go index 2851198..3463b17 100644 --- a/internal/providers/gitea.go +++ b/internal/providers/gitea.go @@ -31,7 +31,7 @@ func NewGiteaClient(url, token *string) *GiteaClient { func (gc *GiteaClient) EditComment( ctx context.Context, - doneRequest *models.RefreshDoneRepositoryRequest, + doneRequest *models.RefreshGiteaRepositoryDoneRequest, ) error { commentBody := html.UnescapeString(doneRequest.CommentBody) startCmnt := "" diff --git a/internal/providers/github.go b/internal/providers/github.go new file mode 100644 index 0000000..217846d --- /dev/null +++ b/internal/providers/github.go @@ -0,0 +1,117 @@ +package providers + +import ( + "context" + "fmt" + "html" + "log" + "net/http" + "strings" + + "git.front.kjuulh.io/kjuulh/contractor/internal/models" + + "github.com/bradleyfalzon/ghinstallation/v2" + "github.com/google/go-github/v53/github" +) + +type GitHubClient struct { + appID *int64 + installationID *int64 + privateKeyPath *string + + client *github.Client +} + +func NewGitHubClient(appID, installationID *int64, privateKeyPath *string) *GitHubClient { + return &GitHubClient{ + appID: appID, + installationID: installationID, + privateKeyPath: privateKeyPath, + } +} + +func (gc *GitHubClient) makeSureClientExist() { + if gc.client != nil { + return + } + + tr := http.DefaultTransport + itr, err := ghinstallation.NewKeyFromFile(tr, *gc.appID, *gc.installationID, *gc.privateKeyPath) + if err != nil { + log.Fatal(err) + } + + client := github.NewClient(&http.Client{Transport: itr}) + + gc.client = client +} + +func (gc *GitHubClient) EditComment( + ctx context.Context, + doneRequest *models.RefreshGitHubRepositoryDoneRequest, +) error { + gc.makeSureClientExist() + + commentBody := html.UnescapeString(doneRequest.CommentBody) + startCmnt := "" + startIdx := strings.Index(commentBody, startCmnt) + endIdx := strings.Index(commentBody, "") + if startIdx >= 0 && endIdx >= 0 { + log.Println("found comment to replace") + + var content string + + if doneRequest.Error != "" { + content = fmt.Sprintf("
ERROR: %s

", doneRequest.Error) + } + if doneRequest.Status != "" { + content = fmt.Sprintf("%s

%s

", content, doneRequest.Status) + } + + doneRequest.CommentBody = fmt.Sprintf( + "%s

%s

%s", + commentBody[:startIdx+len(startCmnt)], + content, + commentBody[endIdx:], + ) + } + + _, _, err := gc.client.Issues.EditComment(ctx, doneRequest.Owner, doneRequest.Repository, int64(doneRequest.CommentID), &github.IssueComment{ + Body: &doneRequest.CommentBody, + }) + if err != nil { + log.Printf("failed to update comment: %s", err.Error()) + return err + } + + return nil +} + +func (gc *GitHubClient) CreateWebhook(owner, repository string) error { + gc.makeSureClientExist() + + // TODO: support for personal access tokens + // We implicitly get support via. github apps + + return nil +} + +func (gc *GitHubClient) AddComment( + owner, repository string, + pullRequest int, + comment string, +) (*models.AddCommentResponse, error) { + gc.makeSureClientExist() + + resp, _, err := gc.client.Issues.CreateComment(context.Background(), owner, repository, pullRequest, &github.IssueComment{ + Body: &comment, + }) + if err != nil { + return nil, err + } + + return &models.AddCommentResponse{ + Body: *resp.Body, + ID: int(*resp.ID), + }, nil +} -- 2.45.2 From 8f924e5dddd0f4449a68b501aebf12de98a593a3 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Wed, 9 Aug 2023 15:46:52 +0200 Subject: [PATCH 16/74] docs(README): update with github support Signed-off-by: kjuulh --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e104758..cc9d973 100644 --- a/README.md +++ b/README.md @@ -41,15 +41,13 @@ what the project will look like once feature-complete. - Includes basic setup such as working server bot, and installation command, automation is missing however. Also only gitea support for now, because this is where the project initially is supposed to be in use. -- [ ] 0.2.0 - - Add GitHub support +- [x] 0.2.0 + - Add GitHub support, only github app support for now. This means that install is not needed, because a github app will automatically receive webhooks if setup properly. docs are missing for this (tbd). - [ ] 0.3.0 - Add Delegation support (not clustering, just delegation of renovate jobs) - [ ] 0.4.0 - Slack integration - [ ] 0.5.0 - - GitHub App and such support -- [ ] 0.6.0 - Add api key support ## Getting started -- 2.45.2 From 647306ea5540cb7519e32c03440a0ee6b11a6edf Mon Sep 17 00:00:00 2001 From: cuddle-please Date: Wed, 9 Aug 2023 13:49:15 +0000 Subject: [PATCH 17/74] chore(release): 0.2.0 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb4775f..f876cb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.2.0] - 2023-08-09 + +### Added +- *(github)* add github support + +### Docs +- *(README)* update with github support + +### Other +- *(app)* split the main command file into multiples + ## [0.1.1] - 2023-08-08 ### Docs -- 2.45.2 From 3a6020813ab9878e0e55176d039fd348f909793d Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Thu, 12 Oct 2023 00:09:06 +0000 Subject: [PATCH 18/74] fix(deps): update all dependencies --- go.mod | 5 +++-- go.sum | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 5f9fd8e..4644823 100644 --- a/go.mod +++ b/go.mod @@ -4,9 +4,11 @@ go 1.20 require ( dagger.io/dagger v0.8.1 + github.com/bradleyfalzon/ghinstallation/v2 v2.6.0 github.com/gin-gonic/gin v1.9.1 github.com/google/go-github/v53 v53.2.0 - github.com/google/uuid v1.3.0 + github.com/google/go-github/v56 v56.0.0 + github.com/google/uuid v1.3.1 github.com/joho/godotenv v1.5.1 github.com/spf13/cobra v1.7.0 ) @@ -16,7 +18,6 @@ require ( github.com/Khan/genqlient v0.6.0 // indirect github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect github.com/adrg/xdg v0.4.0 // indirect - github.com/bradleyfalzon/ghinstallation/v2 v2.6.0 // indirect github.com/bytedance/sonic v1.9.1 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect github.com/cloudflare/circl v1.3.3 // indirect diff --git a/go.sum b/go.sum index e78dc17..de79fee 100644 --- a/go.sum +++ b/go.sum @@ -60,11 +60,14 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v53 v53.2.0 h1:wvz3FyF53v4BK+AsnvCmeNhf8AkTaeh2SoYu/XUvTtI= github.com/google/go-github/v53 v53.2.0/go.mod h1:XhFRObz+m/l+UCm9b7KSIC3lT3NWSXGt7mOsAWEloao= +github.com/google/go-github/v56 v56.0.0/go.mod h1:D8cdcX98YWJvi7TLo7zM4/h8ZTx6u6fwGEkCdisopo0= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -- 2.45.2 From b787bf7058ba4afb5fde3da5e7311aa1385e49dc Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Thu, 12 Oct 2023 00:40:05 +0000 Subject: [PATCH 19/74] fix(deps): update all dependencies --- go.mod | 9 +++++---- go.sum | 10 ++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 4644823..9869e1a 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( dagger.io/dagger v0.8.1 - github.com/bradleyfalzon/ghinstallation/v2 v2.6.0 + github.com/bradleyfalzon/ghinstallation/v2 v2.7.0 github.com/gin-gonic/gin v1.9.1 github.com/google/go-github/v53 v53.2.0 github.com/google/go-github/v56 v56.0.0 @@ -29,6 +29,7 @@ require ( github.com/goccy/go-json v0.10.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/protobuf v1.5.2 // indirect + github.com/google/go-github/v55 v55.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -44,13 +45,13 @@ require ( github.com/ugorji/go/codec v1.2.11 // indirect github.com/vektah/gqlparser/v2 v2.5.6 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.11.0 // indirect + golang.org/x/crypto v0.12.0 // indirect golang.org/x/mod v0.12.0 // indirect golang.org/x/net v0.12.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.10.0 // indirect - golang.org/x/text v0.11.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect golang.org/x/tools v0.11.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.30.0 // indirect diff --git a/go.sum b/go.sum index de79fee..c230cad 100644 --- a/go.sum +++ b/go.sum @@ -16,6 +16,8 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/bradleyfalzon/ghinstallation/v2 v2.6.0 h1:IRY7Xy588KylkoycsUhFpW7cdGpy5Y5BPsz4IfuJtGk= github.com/bradleyfalzon/ghinstallation/v2 v2.6.0/go.mod h1:oQ3etOwN3TRH4EwgW5/7MxSVMGlMlzG/O8TU7eYdoSk= +github.com/bradleyfalzon/ghinstallation/v2 v2.7.0 h1:ranXaC3Zz/F6G/f0Joj3LrFp2OzOKfJZev5Q7OaMc88= +github.com/bradleyfalzon/ghinstallation/v2 v2.7.0/go.mod h1:ymxfmloxXBFXvvF1KpeUhOQM6Dfz9NYtfvTiJyk82UE= github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= @@ -60,6 +62,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v53 v53.2.0 h1:wvz3FyF53v4BK+AsnvCmeNhf8AkTaeh2SoYu/XUvTtI= github.com/google/go-github/v53 v53.2.0/go.mod h1:XhFRObz+m/l+UCm9b7KSIC3lT3NWSXGt7mOsAWEloao= +github.com/google/go-github/v55 v55.0.0 h1:4pp/1tNMB9X/LuAhs5i0KQAE40NmiR/y6prLNb9x9cg= +github.com/google/go-github/v55 v55.0.0/go.mod h1:JLahOTA1DnXzhxEymmFF5PP2tSS9JVNj68mSZNDwskA= github.com/google/go-github/v56 v56.0.0/go.mod h1:D8cdcX98YWJvi7TLo7zM4/h8ZTx6u6fwGEkCdisopo0= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= @@ -132,6 +136,8 @@ golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2Uz golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= @@ -168,6 +174,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -184,6 +192,8 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -- 2.45.2 From ad170717445fe6b0a917004939640b7d6e77c865 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Tue, 17 Oct 2023 02:58:28 +0000 Subject: [PATCH 20/74] fix(deps): update all dependencies --- go.mod | 2 +- go.sum | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 9869e1a..38996d0 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( dagger.io/dagger v0.8.1 - github.com/bradleyfalzon/ghinstallation/v2 v2.7.0 + github.com/bradleyfalzon/ghinstallation/v2 v2.8.0 github.com/gin-gonic/gin v1.9.1 github.com/google/go-github/v53 v53.2.0 github.com/google/go-github/v56 v56.0.0 diff --git a/go.sum b/go.sum index c230cad..a217857 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,8 @@ github.com/bradleyfalzon/ghinstallation/v2 v2.6.0 h1:IRY7Xy588KylkoycsUhFpW7cdGp github.com/bradleyfalzon/ghinstallation/v2 v2.6.0/go.mod h1:oQ3etOwN3TRH4EwgW5/7MxSVMGlMlzG/O8TU7eYdoSk= github.com/bradleyfalzon/ghinstallation/v2 v2.7.0 h1:ranXaC3Zz/F6G/f0Joj3LrFp2OzOKfJZev5Q7OaMc88= github.com/bradleyfalzon/ghinstallation/v2 v2.7.0/go.mod h1:ymxfmloxXBFXvvF1KpeUhOQM6Dfz9NYtfvTiJyk82UE= +github.com/bradleyfalzon/ghinstallation/v2 v2.8.0 h1:yUmoVv70H3J4UOqxqsee39+KlXxNEDfTbAp8c/qULKk= +github.com/bradleyfalzon/ghinstallation/v2 v2.8.0/go.mod h1:fmPmvCiBWhJla3zDv9ZTQSZc8AbwyRnGW1yg5ep1Pcs= github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= @@ -64,6 +66,7 @@ github.com/google/go-github/v53 v53.2.0 h1:wvz3FyF53v4BK+AsnvCmeNhf8AkTaeh2SoYu/ github.com/google/go-github/v53 v53.2.0/go.mod h1:XhFRObz+m/l+UCm9b7KSIC3lT3NWSXGt7mOsAWEloao= github.com/google/go-github/v55 v55.0.0 h1:4pp/1tNMB9X/LuAhs5i0KQAE40NmiR/y6prLNb9x9cg= github.com/google/go-github/v55 v55.0.0/go.mod h1:JLahOTA1DnXzhxEymmFF5PP2tSS9JVNj68mSZNDwskA= +github.com/google/go-github/v56 v56.0.0 h1:TysL7dMa/r7wsQi44BjqlwaHvwlFlqkK8CtBWCX3gb4= github.com/google/go-github/v56 v56.0.0/go.mod h1:D8cdcX98YWJvi7TLo7zM4/h8ZTx6u6fwGEkCdisopo0= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -- 2.45.2 From 7c969f1bd6ed74e9dedafc6199e0e1ad3f30062a Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Thu, 26 Oct 2023 15:01:04 +0000 Subject: [PATCH 21/74] fix(deps): update rust crate futures to 0.3.29 --- ci/Cargo.lock | 36 ++++++++++++++++++------------------ ci/Cargo.toml | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/ci/Cargo.lock b/ci/Cargo.lock index 200628f..c014fe3 100644 --- a/ci/Cargo.lock +++ b/ci/Cargo.lock @@ -541,9 +541,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" dependencies = [ "futures-channel", "futures-core", @@ -556,9 +556,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", "futures-sink", @@ -566,15 +566,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" dependencies = [ "futures-core", "futures-task", @@ -583,15 +583,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", @@ -600,21 +600,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ "futures-channel", "futures-core", diff --git a/ci/Cargo.toml b/ci/Cargo.toml index 0cdb923..d81776a 100644 --- a/ci/Cargo.toml +++ b/ci/Cargo.toml @@ -11,6 +11,6 @@ eyre = "*" color-eyre = "*" tokio = "1" clap = {version = "4", features = ["derive"]} -futures = "0.3.28" +futures = "0.3.29" async-scoped = { version = "0.7.1", features = ["tokio", "use-tokio"] } dotenv = "*" -- 2.45.2 From 8a3155f3e035b6e8903379ad049f453beb90843d Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Thu, 26 Oct 2023 16:10:26 +0000 Subject: [PATCH 22/74] fix(deps): update all dependencies --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 38996d0..c0f1c0a 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/gin-gonic/gin v1.9.1 github.com/google/go-github/v53 v53.2.0 github.com/google/go-github/v56 v56.0.0 - github.com/google/uuid v1.3.1 + github.com/google/uuid v1.4.0 github.com/joho/godotenv v1.5.1 github.com/spf13/cobra v1.7.0 ) diff --git a/go.sum b/go.sum index a217857..ff679d7 100644 --- a/go.sum +++ b/go.sum @@ -75,6 +75,8 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -- 2.45.2 From aaf3bf307f61c2d5f4f3cea55ea2c555b82c2037 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Sat, 4 Nov 2023 21:34:10 +0000 Subject: [PATCH 23/74] fix(deps): update all dependencies --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index c0f1c0a..5712f6a 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/google/go-github/v56 v56.0.0 github.com/google/uuid v1.4.0 github.com/joho/godotenv v1.5.1 - github.com/spf13/cobra v1.7.0 + github.com/spf13/cobra v1.8.0 ) require ( diff --git a/go.sum b/go.sum index ff679d7..8cc4b9a 100644 --- a/go.sum +++ b/go.sum @@ -111,6 +111,8 @@ github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -- 2.45.2 From c7fffdbb4490077753dada9ac9d13249d1693681 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Fri, 1 Dec 2023 18:01:41 +0000 Subject: [PATCH 24/74] fix(deps): update all dependencies --- ci/Cargo.lock | 5 ++--- ci/Cargo.toml | 2 +- go.mod | 3 ++- go.sum | 1 + 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ci/Cargo.lock b/ci/Cargo.lock index c014fe3..4198f96 100644 --- a/ci/Cargo.lock +++ b/ci/Cargo.lock @@ -74,13 +74,12 @@ checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" [[package]] name = "async-scoped" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7a6a57c8aeb40da1ec037f5d455836852f7a57e69e1b1ad3d8f38ac1d6cadf" +checksum = "2bb5d44cd33a5095cf47aa2a90455ea3f9141f45e24d092425fef2bf4fd9c98e" dependencies = [ "futures", "pin-project", - "slab", "tokio", ] diff --git a/ci/Cargo.toml b/ci/Cargo.toml index d81776a..e05e390 100644 --- a/ci/Cargo.toml +++ b/ci/Cargo.toml @@ -12,5 +12,5 @@ color-eyre = "*" tokio = "1" clap = {version = "4", features = ["derive"]} futures = "0.3.29" -async-scoped = { version = "0.7.1", features = ["tokio", "use-tokio"] } +async-scoped = { version = "0.8.0", features = ["tokio", "use-tokio"] } dotenv = "*" diff --git a/go.mod b/go.mod index 5712f6a..862442d 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/bradleyfalzon/ghinstallation/v2 v2.8.0 github.com/gin-gonic/gin v1.9.1 github.com/google/go-github/v53 v53.2.0 - github.com/google/go-github/v56 v56.0.0 + github.com/google/go-github/v57 v57.0.0 github.com/google/uuid v1.4.0 github.com/joho/godotenv v1.5.1 github.com/spf13/cobra v1.8.0 @@ -30,6 +30,7 @@ require ( github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-github/v55 v55.0.0 // indirect + github.com/google/go-github/v56 v56.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect diff --git a/go.sum b/go.sum index 8cc4b9a..fd30b55 100644 --- a/go.sum +++ b/go.sum @@ -68,6 +68,7 @@ github.com/google/go-github/v55 v55.0.0 h1:4pp/1tNMB9X/LuAhs5i0KQAE40NmiR/y6prLN github.com/google/go-github/v55 v55.0.0/go.mod h1:JLahOTA1DnXzhxEymmFF5PP2tSS9JVNj68mSZNDwskA= github.com/google/go-github/v56 v56.0.0 h1:TysL7dMa/r7wsQi44BjqlwaHvwlFlqkK8CtBWCX3gb4= github.com/google/go-github/v56 v56.0.0/go.mod h1:D8cdcX98YWJvi7TLo7zM4/h8ZTx6u6fwGEkCdisopo0= +github.com/google/go-github/v57 v57.0.0/go.mod h1:s0omdnye0hvK/ecLvpsGfJMiRt85PimQh4oygmLIxHw= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -- 2.45.2 From 4c5017f8d39fa15837865c144f398b87e1f29493 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Tue, 12 Dec 2023 17:26:52 +0000 Subject: [PATCH 25/74] fix(deps): update all dependencies --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 862442d..10b3983 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/gin-gonic/gin v1.9.1 github.com/google/go-github/v53 v53.2.0 github.com/google/go-github/v57 v57.0.0 - github.com/google/uuid v1.4.0 + github.com/google/uuid v1.5.0 github.com/joho/godotenv v1.5.1 github.com/spf13/cobra v1.8.0 ) diff --git a/go.sum b/go.sum index fd30b55..e333964 100644 --- a/go.sum +++ b/go.sum @@ -78,6 +78,8 @@ github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -- 2.45.2 From ed2012af251ed3bd741f38218ec7698caa146094 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Sun, 24 Dec 2023 14:57:33 +0000 Subject: [PATCH 26/74] fix(deps): update rust crate futures to 0.3.30 --- ci/Cargo.lock | 36 ++++++++++++++++++------------------ ci/Cargo.toml | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/ci/Cargo.lock b/ci/Cargo.lock index 4198f96..da09dc4 100644 --- a/ci/Cargo.lock +++ b/ci/Cargo.lock @@ -540,9 +540,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -555,9 +555,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -565,15 +565,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -582,15 +582,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", @@ -599,21 +599,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", diff --git a/ci/Cargo.toml b/ci/Cargo.toml index e05e390..3bf9aad 100644 --- a/ci/Cargo.toml +++ b/ci/Cargo.toml @@ -11,6 +11,6 @@ eyre = "*" color-eyre = "*" tokio = "1" clap = {version = "4", features = ["derive"]} -futures = "0.3.29" +futures = "0.3.30" async-scoped = { version = "0.8.0", features = ["tokio", "use-tokio"] } dotenv = "*" -- 2.45.2 From e27d489737770939acc36072745604009b1f30f2 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Fri, 5 Jan 2024 16:10:19 +0000 Subject: [PATCH 27/74] fix(deps): update all dependencies --- go.mod | 2 +- go.sum | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 10b3983..947b1c3 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( dagger.io/dagger v0.8.1 - github.com/bradleyfalzon/ghinstallation/v2 v2.8.0 + github.com/bradleyfalzon/ghinstallation/v2 v2.9.0 github.com/gin-gonic/gin v1.9.1 github.com/google/go-github/v53 v53.2.0 github.com/google/go-github/v57 v57.0.0 diff --git a/go.sum b/go.sum index e333964..82a0379 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,8 @@ github.com/bradleyfalzon/ghinstallation/v2 v2.7.0 h1:ranXaC3Zz/F6G/f0Joj3LrFp2Oz github.com/bradleyfalzon/ghinstallation/v2 v2.7.0/go.mod h1:ymxfmloxXBFXvvF1KpeUhOQM6Dfz9NYtfvTiJyk82UE= github.com/bradleyfalzon/ghinstallation/v2 v2.8.0 h1:yUmoVv70H3J4UOqxqsee39+KlXxNEDfTbAp8c/qULKk= github.com/bradleyfalzon/ghinstallation/v2 v2.8.0/go.mod h1:fmPmvCiBWhJla3zDv9ZTQSZc8AbwyRnGW1yg5ep1Pcs= +github.com/bradleyfalzon/ghinstallation/v2 v2.9.0 h1:HmxIYqnxubRYcYGRc5v3wUekmo5Wv2uX3gukmWJ0AFk= +github.com/bradleyfalzon/ghinstallation/v2 v2.9.0/go.mod h1:wmkTDJf8CmVypxE8ijIStFnKoTa6solK5QfdmJrP9KI= github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= @@ -68,6 +70,7 @@ github.com/google/go-github/v55 v55.0.0 h1:4pp/1tNMB9X/LuAhs5i0KQAE40NmiR/y6prLN github.com/google/go-github/v55 v55.0.0/go.mod h1:JLahOTA1DnXzhxEymmFF5PP2tSS9JVNj68mSZNDwskA= github.com/google/go-github/v56 v56.0.0 h1:TysL7dMa/r7wsQi44BjqlwaHvwlFlqkK8CtBWCX3gb4= github.com/google/go-github/v56 v56.0.0/go.mod h1:D8cdcX98YWJvi7TLo7zM4/h8ZTx6u6fwGEkCdisopo0= +github.com/google/go-github/v57 v57.0.0 h1:L+Y3UPTY8ALM8x+TV0lg+IEBI+upibemtBD8Q9u7zHs= github.com/google/go-github/v57 v57.0.0/go.mod h1:s0omdnye0hvK/ecLvpsGfJMiRt85PimQh4oygmLIxHw= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -- 2.45.2 From f59d4aca3c44fdec714cc7e945a8a20814e7ae5e Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Wed, 10 Jan 2024 03:43:07 +0000 Subject: [PATCH 28/74] fix(deps): update all dependencies to v58 --- go.mod | 3 ++- go.sum | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 947b1c3..33108eb 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/bradleyfalzon/ghinstallation/v2 v2.9.0 github.com/gin-gonic/gin v1.9.1 github.com/google/go-github/v53 v53.2.0 - github.com/google/go-github/v57 v57.0.0 + github.com/google/go-github/v58 v58.0.0 github.com/google/uuid v1.5.0 github.com/joho/godotenv v1.5.1 github.com/spf13/cobra v1.8.0 @@ -31,6 +31,7 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-github/v55 v55.0.0 // indirect github.com/google/go-github/v56 v56.0.0 // indirect + github.com/google/go-github/v57 v57.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect diff --git a/go.sum b/go.sum index 82a0379..20da3d4 100644 --- a/go.sum +++ b/go.sum @@ -72,6 +72,7 @@ github.com/google/go-github/v56 v56.0.0 h1:TysL7dMa/r7wsQi44BjqlwaHvwlFlqkK8CtBW github.com/google/go-github/v56 v56.0.0/go.mod h1:D8cdcX98YWJvi7TLo7zM4/h8ZTx6u6fwGEkCdisopo0= github.com/google/go-github/v57 v57.0.0 h1:L+Y3UPTY8ALM8x+TV0lg+IEBI+upibemtBD8Q9u7zHs= github.com/google/go-github/v57 v57.0.0/go.mod h1:s0omdnye0hvK/ecLvpsGfJMiRt85PimQh4oygmLIxHw= +github.com/google/go-github/v58 v58.0.0/go.mod h1:k4hxDKEfoWpSqFlc8LTpGd9fu2KrV1YAa6Hi6FmDNY4= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -- 2.45.2 From a18951e1ad40841f09bd76c663a92bb5c59c061e Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Tue, 23 Jan 2024 19:49:08 +0000 Subject: [PATCH 29/74] fix(deps): update all dependencies --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 33108eb..2d70953 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/gin-gonic/gin v1.9.1 github.com/google/go-github/v53 v53.2.0 github.com/google/go-github/v58 v58.0.0 - github.com/google/uuid v1.5.0 + github.com/google/uuid v1.6.0 github.com/joho/godotenv v1.5.1 github.com/spf13/cobra v1.8.0 ) diff --git a/go.sum b/go.sum index 20da3d4..0a0b0aa 100644 --- a/go.sum +++ b/go.sum @@ -84,6 +84,8 @@ github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -- 2.45.2 From cc6c71b50f1419b13b19c652d55e46afe248cbf2 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Thu, 21 Mar 2024 15:58:50 +0000 Subject: [PATCH 30/74] fix(deps): update all dependencies --- ci/Cargo.lock | 4 ++-- ci/Cargo.toml | 2 +- go.mod | 8 +++++--- go.sum | 4 ++++ 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ci/Cargo.lock b/ci/Cargo.lock index da09dc4..d9154d6 100644 --- a/ci/Cargo.lock +++ b/ci/Cargo.lock @@ -74,9 +74,9 @@ checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" [[package]] name = "async-scoped" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb5d44cd33a5095cf47aa2a90455ea3f9141f45e24d092425fef2bf4fd9c98e" +checksum = "4042078ea593edffc452eef14e99fdb2b120caa4ad9618bcdeabc4a023b98740" dependencies = [ "futures", "pin-project", diff --git a/ci/Cargo.toml b/ci/Cargo.toml index 3bf9aad..a2e6bb7 100644 --- a/ci/Cargo.toml +++ b/ci/Cargo.toml @@ -12,5 +12,5 @@ color-eyre = "*" tokio = "1" clap = {version = "4", features = ["derive"]} futures = "0.3.30" -async-scoped = { version = "0.8.0", features = ["tokio", "use-tokio"] } +async-scoped = { version = "0.9.0", features = ["tokio", "use-tokio"] } dotenv = "*" diff --git a/go.mod b/go.mod index 2d70953..f394f95 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,15 @@ module git.front.kjuulh.io/kjuulh/contractor -go 1.20 +go 1.21 + +toolchain go1.22.1 require ( dagger.io/dagger v0.8.1 - github.com/bradleyfalzon/ghinstallation/v2 v2.9.0 + github.com/bradleyfalzon/ghinstallation/v2 v2.10.0 github.com/gin-gonic/gin v1.9.1 github.com/google/go-github/v53 v53.2.0 - github.com/google/go-github/v58 v58.0.0 + github.com/google/go-github/v60 v60.0.0 github.com/google/uuid v1.6.0 github.com/joho/godotenv v1.5.1 github.com/spf13/cobra v1.8.0 diff --git a/go.sum b/go.sum index 0a0b0aa..3cbe33c 100644 --- a/go.sum +++ b/go.sum @@ -22,6 +22,8 @@ github.com/bradleyfalzon/ghinstallation/v2 v2.8.0 h1:yUmoVv70H3J4UOqxqsee39+KlXx github.com/bradleyfalzon/ghinstallation/v2 v2.8.0/go.mod h1:fmPmvCiBWhJla3zDv9ZTQSZc8AbwyRnGW1yg5ep1Pcs= github.com/bradleyfalzon/ghinstallation/v2 v2.9.0 h1:HmxIYqnxubRYcYGRc5v3wUekmo5Wv2uX3gukmWJ0AFk= github.com/bradleyfalzon/ghinstallation/v2 v2.9.0/go.mod h1:wmkTDJf8CmVypxE8ijIStFnKoTa6solK5QfdmJrP9KI= +github.com/bradleyfalzon/ghinstallation/v2 v2.10.0 h1:XWuWBRFEpqVrHepQob9yPS3Xg4K3Wr9QCx4fu8HbUNg= +github.com/bradleyfalzon/ghinstallation/v2 v2.10.0/go.mod h1:qoGA4DxWPaYTgVCrmEspVSjlTu4WYAiSxMIhorMRXXc= github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= @@ -73,6 +75,8 @@ github.com/google/go-github/v56 v56.0.0/go.mod h1:D8cdcX98YWJvi7TLo7zM4/h8ZTx6u6 github.com/google/go-github/v57 v57.0.0 h1:L+Y3UPTY8ALM8x+TV0lg+IEBI+upibemtBD8Q9u7zHs= github.com/google/go-github/v57 v57.0.0/go.mod h1:s0omdnye0hvK/ecLvpsGfJMiRt85PimQh4oygmLIxHw= github.com/google/go-github/v58 v58.0.0/go.mod h1:k4hxDKEfoWpSqFlc8LTpGd9fu2KrV1YAa6Hi6FmDNY4= +github.com/google/go-github/v60 v60.0.0 h1:oLG98PsLauFvvu4D/YPxq374jhSxFYdzQGNCyONLfn8= +github.com/google/go-github/v60 v60.0.0/go.mod h1:ByhX2dP9XT9o/ll2yXAu2VD8l5eNVg8hD4Cr0S/LmQk= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -- 2.45.2 From 561bcf084577be305cf2f0281e9bfc58a8f75459 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Mon, 1 Apr 2024 19:29:42 +0000 Subject: [PATCH 31/74] fix(deps): update all dependencies to v61 --- go.mod | 3 ++- go.sum | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index f394f95..cf3357e 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/bradleyfalzon/ghinstallation/v2 v2.10.0 github.com/gin-gonic/gin v1.9.1 github.com/google/go-github/v53 v53.2.0 - github.com/google/go-github/v60 v60.0.0 + github.com/google/go-github/v61 v61.0.0 github.com/google/uuid v1.6.0 github.com/joho/godotenv v1.5.1 github.com/spf13/cobra v1.8.0 @@ -34,6 +34,7 @@ require ( github.com/google/go-github/v55 v55.0.0 // indirect github.com/google/go-github/v56 v56.0.0 // indirect github.com/google/go-github/v57 v57.0.0 // indirect + github.com/google/go-github/v60 v60.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect diff --git a/go.sum b/go.sum index 3cbe33c..b25930d 100644 --- a/go.sum +++ b/go.sum @@ -77,6 +77,7 @@ github.com/google/go-github/v57 v57.0.0/go.mod h1:s0omdnye0hvK/ecLvpsGfJMiRt85Pi github.com/google/go-github/v58 v58.0.0/go.mod h1:k4hxDKEfoWpSqFlc8LTpGd9fu2KrV1YAa6Hi6FmDNY4= github.com/google/go-github/v60 v60.0.0 h1:oLG98PsLauFvvu4D/YPxq374jhSxFYdzQGNCyONLfn8= github.com/google/go-github/v60 v60.0.0/go.mod h1:ByhX2dP9XT9o/ll2yXAu2VD8l5eNVg8hD4Cr0S/LmQk= +github.com/google/go-github/v61 v61.0.0/go.mod h1:0WR+KmsWX75G2EbpyGsGmradjo3IiciuI4BmdVCobQY= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -- 2.45.2 From 0711cf4afa79e6d24a445cc57f58aeba216de8f1 Mon Sep 17 00:00:00 2001 From: cuddle-please Date: Mon, 1 Apr 2024 20:16:38 +0000 Subject: [PATCH 32/74] chore(release): 0.2.1 --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f876cb1..27cebe6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.2.1] - 2024-04-01 + +### Fixed +- *(deps)* update all dependencies to v61 +- *(deps)* update all dependencies +- *(deps)* update all dependencies +- *(deps)* update all dependencies to v58 +- *(deps)* update all dependencies +- *(deps)* update rust crate futures to 0.3.30 +- *(deps)* update all dependencies +- *(deps)* update all dependencies +- *(deps)* update all dependencies +- *(deps)* update all dependencies +- *(deps)* update rust crate futures to 0.3.29 +- *(deps)* update all dependencies +- *(deps)* update all dependencies +- *(deps)* update all dependencies + ## [0.2.0] - 2023-08-09 ### Added -- 2.45.2 From 3ceb52c37805f7a296fc4e3235dbdac4b819784f Mon Sep 17 00:00:00 2001 From: kjuulh Date: Fri, 12 Apr 2024 09:05:04 +0200 Subject: [PATCH 33/74] feat: add base app Signed-off-by: kjuulh --- .drone.yml | 2 + .env | 1 + .gitignore | 2 + Cargo.lock | 2305 +++++++++++++++++ Cargo.toml | 14 + README.md | 1 + crates/contractor/.gitignore | 1 + crates/contractor/Cargo.toml | 19 + .../crdb/20240201211013_initial.sql | 1 + crates/contractor/src/api.rs | 40 + crates/contractor/src/main.rs | 62 + crates/contractor/src/schedule.rs | 14 + crates/contractor/src/state.rs | 41 + cuddle.yaml | 21 + renovate.json | 3 + templates/docker-compose.yaml | 15 + 16 files changed, 2542 insertions(+) create mode 100644 .drone.yml create mode 100644 .env create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 crates/contractor/.gitignore create mode 100644 crates/contractor/Cargo.toml create mode 100644 crates/contractor/migrations/crdb/20240201211013_initial.sql create mode 100644 crates/contractor/src/api.rs create mode 100644 crates/contractor/src/main.rs create mode 100644 crates/contractor/src/schedule.rs create mode 100644 crates/contractor/src/state.rs create mode 100644 cuddle.yaml create mode 100644 renovate.json create mode 100644 templates/docker-compose.yaml diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..62e235e --- /dev/null +++ b/.drone.yml @@ -0,0 +1,2 @@ +kind: template +load: cuddle-rust-service-plan.yaml diff --git a/.env b/.env new file mode 100644 index 0000000..119ed0d --- /dev/null +++ b/.env @@ -0,0 +1 @@ + DATABASE_URL="postgres://root@localhost:26257/defaultdb?sslmode=disable" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9c4c004 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +target/ +.cuddle/ diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..3158081 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2305 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "anstream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" + +[[package]] +name = "anstyle-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + +[[package]] +name = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atomic-write-file" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436" +dependencies = [ + "nix", + "rand", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "axum" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1236b4b292f6c4d6dc34604bb5120d85c3fe1d1aa596bd5cc52ca054d13e7b9e" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +dependencies = [ + "serde", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80672091db20273a15cf9fdd4e47ed43b5091ec9841bf4c6145c9dfbbcae09ed" +dependencies = [ + "clap_builder", + "clap_derive", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1458a1df40e1e2afebb7ab60ce55c1fa8f431146205aa5f4887e0b111c27636" +dependencies = [ + "anstream", + "anstyle", + "bitflags 1.3.2", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "clap_lex" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "contractor" +version = "0.1.0" +dependencies = [ + "anyhow", + "axum", + "clap", + "dotenv", + "futures", + "serde", + "sqlx", + "tokio", + "tower-http", + "tracing", + "tracing-subscriber", + "uuid", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +dependencies = [ + "serde", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "spin 0.9.8", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "h2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31d030e59af851932b72ceebadf4a2b5986dba4c3b99dd2493f8273a0f151943" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "http" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "hyper" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2 0.5.5", + "tokio", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433de089bd45971eecf4668ee0ee8f4cec17db4f8bd8f7bc3197a6ce37aa7d9b" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "is-terminal" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix 0.37.20", + "windows-sys 0.48.0", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "matchit" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.4.2", + "cfg-if", + "libc", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi 0.2.6", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.3.5", + "smallvec", + "windows-targets 0.48.0", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pin-project" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "ring" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babe80d5c16becf6594aa32ad2be8fe08498e7ae60b77de8df700e67f191d7e" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted", + "windows-sys 0.48.0", +] + +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustix" +version = "0.37.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +dependencies = [ + "bitflags 2.4.2", + "errno", + "libc", + "linux-raw-sys 0.4.13", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_json" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7f05c1d5476066defcdfacce1f52fc3cae3af1d3089727100c02ae92e5abbe0" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlformat" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" +dependencies = [ + "itertools", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" +dependencies = [ + "ahash", + "atoi", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "dotenvy", + "either", + "event-listener", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashlink", + "hex", + "indexmap", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlformat", + "thiserror", + "time", + "tokio", + "tokio-stream", + "tracing", + "url", + "uuid", + "webpki-roots", +] + +[[package]] +name = "sqlx-macros" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" +dependencies = [ + "atomic-write-file", + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 1.0.109", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" +dependencies = [ + "atoi", + "base64", + "bitflags 2.4.2", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" +dependencies = [ + "atoi", + "base64", + "bitflags 2.4.2", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand", + "serde", + "serde_json", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core", + "time", + "tracing", + "url", + "urlencoding", + "uuid", +] + +[[package]] +name = "stringprep" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +dependencies = [ + "finl_unicode", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "tempfile" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.4.1", + "rustix 0.38.31", + "windows-sys 0.52.0", +] + +[[package]] +name = "thiserror" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +dependencies = [ + "deranged", + "itoa", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.28.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +dependencies = [ + "autocfg", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.4.9", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" +dependencies = [ + "bitflags 2.4.2", + "bytes", + "http", + "http-body", + "http-body-util", + "pin-project-lite", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" +dependencies = [ + "getrandom", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "webpki-roots" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" + +[[package]] +name = "whoami" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..caa2e24 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,14 @@ +[workspace] +members = ["crates/*"] +resolver = "2" + +[workspace.dependencies] +contractor = { path = "crates/contractor" } + +anyhow = { version = "1" } +tokio = { version = "1", features = ["full"] } +tracing = { version = "0.1", features = ["log"] } +tracing-subscriber = { version = "0.3.18" } +clap = { version = "4", features = ["derive", "env"] } +dotenv = { version = "0.15" } +axum = { version = "0.7" } diff --git a/README.md b/README.md new file mode 100644 index 0000000..cef8c74 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# contractor diff --git a/crates/contractor/.gitignore b/crates/contractor/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/crates/contractor/.gitignore @@ -0,0 +1 @@ +/target diff --git a/crates/contractor/Cargo.toml b/crates/contractor/Cargo.toml new file mode 100644 index 0000000..5e2bd3b --- /dev/null +++ b/crates/contractor/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "contractor" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow.workspace = true +tokio.workspace = true +tracing.workspace = true +tracing-subscriber.workspace = true +clap.workspace = true +dotenv.workspace = true +axum.workspace = true + +serde = { version = "1.0.197", features = ["derive"] } +sqlx = { version = "0.7.3", features = ["runtime-tokio", "tls-rustls", "postgres", "uuid", "time"] } +uuid = { version = "1.7.0", features = ["v4"] } +tower-http = { version = "0.5.2", features = ["cors", "trace"] } +futures = "0.3.30" diff --git a/crates/contractor/migrations/crdb/20240201211013_initial.sql b/crates/contractor/migrations/crdb/20240201211013_initial.sql new file mode 100644 index 0000000..8ddc1d3 --- /dev/null +++ b/crates/contractor/migrations/crdb/20240201211013_initial.sql @@ -0,0 +1 @@ +-- Add migration script here diff --git a/crates/contractor/src/api.rs b/crates/contractor/src/api.rs new file mode 100644 index 0000000..192c9fd --- /dev/null +++ b/crates/contractor/src/api.rs @@ -0,0 +1,40 @@ +use std::net::SocketAddr; + +use axum::{extract::MatchedPath, http::Request, routing::get, Router}; +use tower_http::trace::TraceLayer; + +use crate::SharedState; + +pub async fn serve_axum(state: &SharedState, host: &SocketAddr) -> Result<(), anyhow::Error> { + tracing::info!("running webhook server"); + let app = Router::new() + .route("/", get(root)) + .with_state(state.clone()) + .layer( + TraceLayer::new_for_http().make_span_with(|request: &Request<_>| { + // Log the matched route's path (with placeholders not filled in). + // Use request.uri() or OriginalUri if you want the real path. + let matched_path = request + .extensions() + .get::() + .map(MatchedPath::as_str); + + tracing::info_span!( + "http_request", + method = ?request.method(), + matched_path, + some_other_field = tracing::field::Empty, + ) + }), // ... + ); + + tracing::info!("listening on {}", host); + let listener = tokio::net::TcpListener::bind(host).await.unwrap(); + axum::serve(listener, app.into_make_service()).await?; + + Ok(()) +} + +async fn root() -> &'static str { + "Hello, contractor!" +} diff --git a/crates/contractor/src/main.rs b/crates/contractor/src/main.rs new file mode 100644 index 0000000..e737017 --- /dev/null +++ b/crates/contractor/src/main.rs @@ -0,0 +1,62 @@ +use std::{net::SocketAddr, sync::Arc}; + +use clap::{Parser, Subcommand}; +use futures::{stream::FuturesUnordered, StreamExt}; +use tokio::task; + +#[derive(Parser)] +#[command(author, version, about, long_about = None, subcommand_required = true)] +struct Command { + #[command(subcommand)] + command: Option, +} + +#[derive(Subcommand)] +enum Commands { + Serve { + #[arg(env = "SERVICE_HOST", long, default_value = "127.0.0.1:3000")] + host: SocketAddr, + }, +} + +mod api; +mod schedule; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + dotenv::dotenv().ok(); + tracing_subscriber::fmt::init(); + + let cli = Command::parse(); + + if let Some(Commands::Serve { host }) = cli.command { + tracing::info!("Starting service"); + + let state = SharedState::from(Arc::new(State::new().await?)); + + let mut tasks = FuturesUnordered::new(); + + tasks.push({ + let state = state.clone(); + task::spawn(async move { + serve_axum(&state, &host).await?; + Ok::<(), anyhow::Error>(()) + }) + }); + + tasks.push(task::spawn(async move { + serve_cron_jobs(&state).await?; + Ok::<(), anyhow::Error>(()) + })); + + while let Some(result) = tasks.next().await { + result?? + } + } + + Ok(()) +} + +mod state; +pub use crate::state::{SharedState, State}; +use crate::{api::serve_axum, schedule::serve_cron_jobs}; diff --git a/crates/contractor/src/schedule.rs b/crates/contractor/src/schedule.rs new file mode 100644 index 0000000..9d6117c --- /dev/null +++ b/crates/contractor/src/schedule.rs @@ -0,0 +1,14 @@ +use crate::SharedState; + +pub async fn serve_cron_jobs(_state: &SharedState) -> Result<(), anyhow::Error> { + tokio::spawn(async move { + loop { + tracing::info!("running cronjobs"); + tokio::time::sleep(std::time::Duration::from_secs(10_000)).await; + } + Ok::<(), anyhow::Error>(()) + }) + .await??; + + Ok(()) +} diff --git a/crates/contractor/src/state.rs b/crates/contractor/src/state.rs new file mode 100644 index 0000000..c98c782 --- /dev/null +++ b/crates/contractor/src/state.rs @@ -0,0 +1,41 @@ +use std::{ops::Deref, sync::Arc}; + +#[derive(Clone)] +pub struct SharedState(Arc); + +impl From> for SharedState { + fn from(value: Arc) -> Self { + Self(value) + } +} + +impl Deref for SharedState { + type Target = Arc; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +pub struct State { + // pub db: Pool, +} + +impl State { + pub async fn new() -> anyhow::Result { + // let db = sqlx::PgPool::connect( + // &std::env::var("DATABASE_URL").context("DATABASE_URL is not set")?, + // ) + // .await?; + + // sqlx::migrate!("migrations/crdb") + // .set_locking(false) + // .run(&db) + // .await?; + + // let _ = sqlx::query("SELECT 1;").fetch_one(&db).await?; + + // Ok(Self { db }) + Ok(Self {}) + } +} diff --git a/cuddle.yaml b/cuddle.yaml new file mode 100644 index 0000000..a900b1c --- /dev/null +++ b/cuddle.yaml @@ -0,0 +1,21 @@ +# yaml-language-server: $schema=https://git.front.kjuulh.io/kjuulh/cuddle/raw/branch/main/schemas/base.json + +base: "git@git.front.kjuulh.io:kjuulh/cuddle-rust-service-plan.git" + +vars: + service: "contractor" + registry: kasperhermansen + + clusters: + clank-prod: + replicas: "3" + namespace: prod + + +deployment: + registry: git@git.front.kjuulh.io:kjuulh/clank-clusters + env: + prod: + clusters: + - clank-prod + diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..7190a60 --- /dev/null +++ b/renovate.json @@ -0,0 +1,3 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json" +} diff --git a/templates/docker-compose.yaml b/templates/docker-compose.yaml new file mode 100644 index 0000000..8fae72a --- /dev/null +++ b/templates/docker-compose.yaml @@ -0,0 +1,15 @@ +version: "3" +services: + crdb: + restart: 'always' + image: 'cockroachdb/cockroach:v23.1.14' + command: 'start-single-node --advertise-addr 0.0.0.0 --insecure' + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/health?ready=1"] + interval: '10s' + timeout: '30s' + retries: 5 + start_period: '20s' + ports: + - 8080:8080 + - '26257:26257' -- 2.45.2 From 9cbef537c975d34b3906507971cd73726b23e0ae Mon Sep 17 00:00:00 2001 From: kjuulh Date: Fri, 12 Apr 2024 16:17:43 +0200 Subject: [PATCH 34/74] feat: add support for reading from gitea Signed-off-by: kjuulh --- .env | 1 - .gitignore | 1 + Cargo.lock | 993 +++++++++++------- crates/contractor/Cargo.toml | 1 + crates/contractor/src/main.rs | 55 +- crates/contractor/src/schedule.rs | 9 +- crates/contractor/src/services.rs | 2 + crates/contractor/src/services/gitea.rs | 147 +++ .../src/services/gitea/extensions.rs | 11 + .../contractor/src/services/gitea/traits.rs | 17 + crates/contractor/src/services/reconciler.rs | 58 + crates/contractor/src/state.rs | 2 + 12 files changed, 885 insertions(+), 412 deletions(-) delete mode 100644 .env create mode 100644 crates/contractor/src/services.rs create mode 100644 crates/contractor/src/services/gitea.rs create mode 100644 crates/contractor/src/services/gitea/extensions.rs create mode 100644 crates/contractor/src/services/gitea/traits.rs create mode 100644 crates/contractor/src/services/reconciler.rs diff --git a/.env b/.env deleted file mode 100644 index 119ed0d..0000000 --- a/.env +++ /dev/null @@ -1 +0,0 @@ - DATABASE_URL="postgres://root@localhost:26257/defaultdb?sslmode=disable" diff --git a/.gitignore b/.gitignore index 9c4c004..44911c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ target/ .cuddle/ +.env diff --git a/Cargo.lock b/Cargo.lock index 3158081..8e2db86 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,10 +3,25 @@ version = 3 [[package]] -name = "ahash" -version = "0.8.7" +name = "addr2line" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "getrandom", @@ -17,74 +32,73 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "anstream" -version = "0.3.2" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.0" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" -version = "0.2.0" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "1.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.58", ] [[package]] @@ -96,27 +110,17 @@ dependencies = [ "num-traits", ] -[[package]] -name = "atomic-write-file" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436" -dependencies = [ - "nix", - "rand", -] - [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "axum" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1236b4b292f6c4d6dc34604bb5120d85c3fe1d1aa596bd5cc52ca054d13e7b9e" +checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" dependencies = [ "async-trait", "axum-core", @@ -138,7 +142,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 1.0.1", "tokio", "tower", "tower-layer", @@ -161,18 +165,39 @@ dependencies = [ "mime", "pin-project-lite", "rustversion", - "sync_wrapper", + "sync_wrapper 0.1.2", "tower-layer", "tower-service", "tracing", ] +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" + [[package]] name = "base64ct" version = "1.6.0" @@ -187,9 +212,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" dependencies = [ "serde", ] @@ -203,6 +228,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "byteorder" version = "1.5.0" @@ -211,15 +242,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.4.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41" [[package]] name = "cfg-if" @@ -229,45 +260,43 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.3.4" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80672091db20273a15cf9fdd4e47ed43b5091ec9841bf4c6145c9dfbbcae09ed" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", "clap_derive", - "once_cell", ] [[package]] name = "clap_builder" -version = "4.3.4" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1458a1df40e1e2afebb7ab60ce55c1fa8f431146205aa5f4887e0b111c27636" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", - "bitflags 1.3.2", "clap_lex", "strsim", ] [[package]] name = "clap_derive" -version = "4.3.2" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.58", ] [[package]] name = "clap_lex" -version = "0.5.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "colorchoice" @@ -290,6 +319,7 @@ dependencies = [ "clap", "dotenv", "futures", + "reqwest", "serde", "sqlx", "tokio", @@ -310,9 +340,9 @@ dependencies = [ [[package]] name = "crc" -version = "3.0.1" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" dependencies = [ "crc-catalog", ] @@ -350,9 +380,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "pem-rfc7468", @@ -394,9 +424,9 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "either" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" dependencies = [ "serde", ] @@ -436,9 +466,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fastrand" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" [[package]] name = "finl_unicode" @@ -465,9 +495,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -539,7 +569,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.58", ] [[package]] @@ -584,9 +614,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" dependencies = [ "cfg-if", "libc", @@ -594,23 +624,10 @@ dependencies = [ ] [[package]] -name = "h2" -version = "0.4.2" +name = "gimli" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31d030e59af851932b72ceebadf4a2b5986dba4c3b99dd2493f8273a0f151943" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "hashbrown" @@ -641,19 +658,16 @@ dependencies = [ ] [[package]] -name = "hermit-abi" -version = "0.2.6" +name = "heck" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.1" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -690,9 +704,9 @@ dependencies = [ [[package]] name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -711,12 +725,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" dependencies = [ "bytes", - "futures-util", + "futures-core", "http", "http-body", "pin-project-lite", @@ -730,27 +744,45 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75" +checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" dependencies = [ "bytes", "futures-channel", "futures-util", - "h2", "http", "http-body", "httparse", "httpdate", "itoa", "pin-project-lite", + "smallvec", "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" +dependencies = [ + "futures-util", + "http", + "hyper", + "hyper-util", + "rustls 0.22.3", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", ] [[package]] @@ -760,20 +792,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" dependencies = [ "bytes", + "futures-channel", "futures-util", "http", "http-body", "hyper", "pin-project-lite", - "socket2 0.5.5", + "socket2", "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -781,36 +817,19 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.1" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433de089bd45971eecf4668ee0ee8f4cec17db4f8bd8f7bc3197a6ce37aa7d9b" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown", ] [[package]] -name = "io-lifetimes" -version = "1.0.11" +name = "ipnet" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.1", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "is-terminal" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" -dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes", - "rustix 0.37.20", - "windows-sys 0.48.0", -] +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "itertools" @@ -823,9 +842,18 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] [[package]] name = "lazy_static" @@ -859,12 +887,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -873,9 +895,9 @@ checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -883,15 +905,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "matchit" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "md-5" @@ -905,9 +927,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "mime" @@ -922,27 +944,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] -name = "mio" -version = "0.8.8" +name = "miniz_oxide" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "wasi", "windows-sys 0.48.0", ] -[[package]] -name = "nix" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" -dependencies = [ - "bitflags 2.4.2", - "cfg-if", - "libc", -] - [[package]] name = "nom" version = "7.1.3" @@ -981,20 +1001,25 @@ dependencies = [ ] [[package]] -name = "num-integer" -version = "0.1.45" +name = "num-conv" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" dependencies = [ "autocfg", "num-integer", @@ -1003,9 +1028,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", "libm", @@ -1013,19 +1038,28 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "libc", ] [[package]] -name = "once_cell" -version = "1.18.0" +name = "object" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "overload" @@ -1045,15 +1079,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall", "smallvec", - "windows-targets 0.48.0", + "windows-targets 0.48.5", ] [[package]] @@ -1073,35 +1107,35 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.1.0" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.0" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.58", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1132,9 +1166,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "powerfmt" @@ -1150,18 +1184,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -1196,15 +1230,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -1215,17 +1240,59 @@ dependencies = [ ] [[package]] -name = "ring" -version = "0.17.3" +name = "reqwest" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babe80d5c16becf6594aa32ad2be8fe08498e7ae60b77de8df700e67f191d7e" +checksum = "3e6cc1e89e689536eb5aeede61520e874df5a4707df811cd5da4aa5fbb2aae19" +dependencies = [ + "base64 0.22.0", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.22.3", + "rustls-pemfile 2.1.2", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 0.1.2", + "tokio", + "tokio-rustls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.26.1", + "winreg", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin 0.9.8", "untrusted", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1249,29 +1316,21 @@ dependencies = [ ] [[package]] -name = "rustix" -version = "0.37.20" +name = "rustc-demangle" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", -] +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "errno", "libc", - "linux-raw-sys 0.4.13", + "linux-raw-sys", "windows-sys 0.52.0", ] @@ -1282,19 +1341,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "ring", - "rustls-webpki", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.2", + "subtle", + "zeroize", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64", + "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.0", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -1306,22 +1395,33 @@ dependencies = [ ] [[package]] -name = "rustversion" -version = "1.0.12" +name = "rustls-webpki" +version = "0.102.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" @@ -1350,14 +1450,14 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.58", ] [[package]] name = "serde_json" -version = "1.0.97" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" dependencies = [ "itoa", "ryu", @@ -1366,10 +1466,11 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.11" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7f05c1d5476066defcdfacce1f52fc3cae3af1d3089727100c02ae92e5abbe0" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" dependencies = [ + "itoa", "serde", ] @@ -1409,9 +1510,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -1446,28 +1547,18 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.10.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.4.9" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "winapi", -] - -[[package]] -name = "socket2" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" -dependencies = [ - "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1508,9 +1599,9 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" +checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa" dependencies = [ "sqlx-core", "sqlx-macros", @@ -1521,9 +1612,9 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" +checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6" dependencies = [ "ahash", "atoi", @@ -1531,7 +1622,6 @@ dependencies = [ "bytes", "crc", "crossbeam-queue", - "dotenvy", "either", "event-listener", "futures-channel", @@ -1547,8 +1637,8 @@ dependencies = [ "once_cell", "paste", "percent-encoding", - "rustls", - "rustls-pemfile", + "rustls 0.21.10", + "rustls-pemfile 1.0.4", "serde", "serde_json", "sha2", @@ -1561,14 +1651,14 @@ dependencies = [ "tracing", "url", "uuid", - "webpki-roots", + "webpki-roots 0.25.4", ] [[package]] name = "sqlx-macros" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" +checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127" dependencies = [ "proc-macro2", "quote", @@ -1579,14 +1669,13 @@ dependencies = [ [[package]] name = "sqlx-macros-core" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" +checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8" dependencies = [ - "atomic-write-file", "dotenvy", "either", - "heck", + "heck 0.4.1", "hex", "once_cell", "proc-macro2", @@ -1606,13 +1695,13 @@ dependencies = [ [[package]] name = "sqlx-mysql" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" +checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" dependencies = [ "atoi", - "base64", - "bitflags 2.4.2", + "base64 0.21.7", + "bitflags 2.5.0", "byteorder", "bytes", "crc", @@ -1650,13 +1739,13 @@ dependencies = [ [[package]] name = "sqlx-postgres" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" +checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" dependencies = [ "atoi", - "base64", - "bitflags 2.4.2", + "base64 0.21.7", + "bitflags 2.5.0", "byteorder", "crc", "dotenvy", @@ -1677,7 +1766,6 @@ dependencies = [ "rand", "serde", "serde_json", - "sha1", "sha2", "smallvec", "sqlx-core", @@ -1691,9 +1779,9 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490" +checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa" dependencies = [ "atoi", "flume", @@ -1727,9 +1815,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" @@ -1750,9 +1838,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ "proc-macro2", "quote", @@ -1766,43 +1854,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] -name = "tempfile" -version = "3.9.0" +name = "sync_wrapper" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", - "redox_syscall 0.4.1", - "rustix 0.38.31", + "rustix", "windows-sys 0.52.0", ] [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.58", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -1810,12 +1903,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -1830,10 +1924,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -1854,11 +1949,11 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.2" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", "mio", @@ -1866,47 +1961,44 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.4.9", + "socket2", "tokio-macros", "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.58", +] + +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls 0.22.3", + "rustls-pki-types", + "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", "pin-project-lite", "tokio", ] -[[package]] -name = "tokio-util" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - [[package]] name = "tower" version = "0.4.13" @@ -1929,7 +2021,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "bytes", "http", "http-body", @@ -1954,11 +2046,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "log", "pin-project-lite", "tracing-attributes", @@ -1967,20 +2058,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.24" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.58", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", @@ -2011,6 +2102,12 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "typenum" version = "1.17.0" @@ -2025,24 +2122,24 @@ checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode_categories" @@ -2058,9 +2155,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -2081,9 +2178,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ "getrandom", ] @@ -2106,6 +2203,15 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2113,16 +2219,111 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "webpki-roots" -version = "0.25.3" +name = "wasite" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.58", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.58", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "webpki-roots" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +dependencies = [ + "rustls-pki-types", +] [[package]] name = "whoami" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" +checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +dependencies = [ + "redox_syscall", + "wasite", +] [[package]] name = "winapi" @@ -2152,7 +2353,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.5", ] [[package]] @@ -2161,122 +2362,132 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + +[[package]] +name = "winreg" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] [[package]] name = "zerocopy" @@ -2295,7 +2506,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.58", ] [[package]] diff --git a/crates/contractor/Cargo.toml b/crates/contractor/Cargo.toml index 5e2bd3b..eeec02c 100644 --- a/crates/contractor/Cargo.toml +++ b/crates/contractor/Cargo.toml @@ -17,3 +17,4 @@ sqlx = { version = "0.7.3", features = ["runtime-tokio", "tls-rustls", "postgres uuid = { version = "1.7.0", features = ["v4"] } tower-http = { version = "0.5.2", features = ["cors", "trace"] } futures = "0.3.30" +reqwest = {version = "0.12.3", default-features = false, features = ["json", "rustls-tls"]} diff --git a/crates/contractor/src/main.rs b/crates/contractor/src/main.rs index e737017..f93c5a5 100644 --- a/crates/contractor/src/main.rs +++ b/crates/contractor/src/main.rs @@ -17,6 +17,13 @@ enum Commands { #[arg(env = "SERVICE_HOST", long, default_value = "127.0.0.1:3000")] host: SocketAddr, }, + + Reconcile { + #[arg(long)] + user: Option, + #[arg(long)] + orgs: Option>, + }, } mod api; @@ -29,29 +36,39 @@ async fn main() -> anyhow::Result<()> { let cli = Command::parse(); - if let Some(Commands::Serve { host }) = cli.command { - tracing::info!("Starting service"); + match cli.command { + Some(Commands::Serve { host }) => { + tracing::info!("Starting service"); - let state = SharedState::from(Arc::new(State::new().await?)); + let state = SharedState::from(Arc::new(State::new().await?)); - let mut tasks = FuturesUnordered::new(); + let mut tasks = FuturesUnordered::new(); - tasks.push({ - let state = state.clone(); - task::spawn(async move { - serve_axum(&state, &host).await?; + tasks.push({ + let state = state.clone(); + task::spawn(async move { + serve_axum(&state, &host).await?; + Ok::<(), anyhow::Error>(()) + }) + }); + + tasks.push(task::spawn(async move { + serve_cron_jobs(&state).await?; Ok::<(), anyhow::Error>(()) - }) - }); + })); - tasks.push(task::spawn(async move { - serve_cron_jobs(&state).await?; - Ok::<(), anyhow::Error>(()) - })); - - while let Some(result) = tasks.next().await { - result?? + while let Some(result) = tasks.next().await { + result?? + } } + Some(Commands::Reconcile { user, orgs }) => { + tracing::info!("running reconcile"); + + let state = SharedState::from(Arc::new(State::new().await?)); + + state.reconciler().reconcile(user, orgs).await?; + } + None => {} } Ok(()) @@ -59,4 +76,6 @@ async fn main() -> anyhow::Result<()> { mod state; pub use crate::state::{SharedState, State}; -use crate::{api::serve_axum, schedule::serve_cron_jobs}; +use crate::{api::serve_axum, schedule::serve_cron_jobs, services::reconciler::ReconcilerState}; + +mod services; diff --git a/crates/contractor/src/schedule.rs b/crates/contractor/src/schedule.rs index 9d6117c..4cdad94 100644 --- a/crates/contractor/src/schedule.rs +++ b/crates/contractor/src/schedule.rs @@ -1,9 +1,14 @@ -use crate::SharedState; +use crate::{services::gitea::GiteaClientState, SharedState}; -pub async fn serve_cron_jobs(_state: &SharedState) -> Result<(), anyhow::Error> { +pub async fn serve_cron_jobs(state: &SharedState) -> Result<(), anyhow::Error> { + let state = state.clone(); tokio::spawn(async move { + let gitea_client = state.gitea_client(); loop { tracing::info!("running cronjobs"); + + todo!(); + tokio::time::sleep(std::time::Duration::from_secs(10_000)).await; } Ok::<(), anyhow::Error>(()) diff --git a/crates/contractor/src/services.rs b/crates/contractor/src/services.rs new file mode 100644 index 0000000..40a9bcd --- /dev/null +++ b/crates/contractor/src/services.rs @@ -0,0 +1,2 @@ +pub mod gitea; +pub mod reconciler; diff --git a/crates/contractor/src/services/gitea.rs b/crates/contractor/src/services/gitea.rs new file mode 100644 index 0000000..2a164da --- /dev/null +++ b/crates/contractor/src/services/gitea.rs @@ -0,0 +1,147 @@ +use std::{ops::Deref, pin::Pin, sync::Arc}; + +type DynGiteaClient = Arc; +pub struct GiteaClient(DynGiteaClient); + +impl GiteaClient { + pub fn new() -> Self { + Self(Arc::new(DefaultGiteaClient::default())) + } +} + +impl Deref for GiteaClient { + type Target = DynGiteaClient; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Clone, Debug)] +pub struct Repository { + pub owner: String, + pub name: String, +} + +impl TryFrom for Repository { + type Error = anyhow::Error; + + fn try_from(value: GiteaRepository) -> Result { + let (owner, name) = value + .full_name + .split_once('/') + .ok_or(anyhow::anyhow!( + "name of repository is invalid, should contain a /" + )) + .map_err(|e| { + tracing::warn!("failed to parse repository: {}", e); + + e + })?; + + Ok(Repository { + owner: owner.into(), + name: name.into(), + }) + } +} + +#[derive(Clone, Debug, Deserialize)] +pub struct GiteaRepository { + full_name: String, +} + +pub struct DefaultGiteaClient { + url: String, + token: String, +} + +impl Default for DefaultGiteaClient { + fn default() -> Self { + Self { + url: std::env::var("GITEA_URL") + .context("GITEA_URL should be set") + .map(|g| g.trim_end_matches('/').to_string()) + .unwrap(), + token: std::env::var("GITEA_TOKEN") + .context("GITEA_TOKEN should be set") + .unwrap(), + } + } +} + +impl DefaultGiteaClient { + pub async fn fetch_user_repos(&self) -> anyhow::Result> { + let client = reqwest::Client::new(); + + let url = format!("{}/api/v1/user/repos", self.url); + + tracing::trace!("calling url: {}", &url); + + let response = client + .get(&url) + .header("Content-Type", "application/json") + .header("Authorization", format!("token {}", self.token)) + .send() + .await?; + + let repositories = response.json::>().await?; + + Ok(repositories + .into_iter() + .flat_map(Repository::try_from) + .collect()) + } + + pub async fn fetch_org_repos(&self, org: &str) -> anyhow::Result> { + let client = reqwest::Client::new(); + + let url = format!("{}/api/v1/orgs/{}/repos", self.url, org); + + tracing::trace!("calling url: {}", &url); + + let response = client + .get(&url) + .header("Content-Type", "application/json") + .header("Authorization", format!("token {}", self.token)) + .send() + .await?; + + let repositories = response.json::>().await?; + + Ok(repositories + .into_iter() + .flat_map(Repository::try_from) + .collect()) + } +} + +impl traits::GiteaClient for DefaultGiteaClient { + fn get_user_repositories<'a>( + &'a self, + user: &str, + ) -> Pin>> + Send + 'a>> + { + tracing::debug!("fetching gitea repositories for user: {user}"); + + Box::pin(async { self.fetch_user_repos().await }) + } + + fn get_org_repositories<'a>( + &'a self, + org: &'a str, + ) -> Pin>> + Send + 'a>> + { + tracing::debug!("fetching gitea repositories for org: {org}"); + + Box::pin(async move { self.fetch_org_repos(org).await }) + } +} + +mod extensions; +pub mod traits; + +use anyhow::Context; +use axum::http::HeaderMap; +pub use extensions::*; +use serde::Deserialize; diff --git a/crates/contractor/src/services/gitea/extensions.rs b/crates/contractor/src/services/gitea/extensions.rs new file mode 100644 index 0000000..6d91e8d --- /dev/null +++ b/crates/contractor/src/services/gitea/extensions.rs @@ -0,0 +1,11 @@ +use crate::SharedState; + +use super::GiteaClient; + +pub trait GiteaClientState { + fn gitea_client(&self) -> GiteaClient { + GiteaClient::new() + } +} + +impl GiteaClientState for SharedState {} diff --git a/crates/contractor/src/services/gitea/traits.rs b/crates/contractor/src/services/gitea/traits.rs new file mode 100644 index 0000000..27daf5a --- /dev/null +++ b/crates/contractor/src/services/gitea/traits.rs @@ -0,0 +1,17 @@ +use std::pin::Pin; + +use futures::Future; + +use super::Repository; + +pub trait GiteaClient { + fn get_user_repositories<'a>( + &'a self, + user: &str, + ) -> Pin>> + Send + 'a>>; + + fn get_org_repositories<'a>( + &'a self, + org: &'a str, + ) -> Pin>> + Send + 'a>>; +} diff --git a/crates/contractor/src/services/reconciler.rs b/crates/contractor/src/services/reconciler.rs new file mode 100644 index 0000000..458721c --- /dev/null +++ b/crates/contractor/src/services/reconciler.rs @@ -0,0 +1,58 @@ +use crate::SharedState; + +use super::gitea::{GiteaClient, GiteaClientState, Repository}; + +pub struct Reconciler { + gitea_client: GiteaClient, +} + +impl Reconciler { + pub fn new(gitea_client: GiteaClient) -> Self { + Self { gitea_client } + } + + pub async fn reconcile( + &self, + user: Option, + orgs: Option>, + ) -> anyhow::Result<()> { + let repos = self.get_repos(user, orgs).await?; + + tracing::info!("found repositories: {}", repos.len()); + + Ok(()) + } + + async fn get_repos( + &self, + user: Option, + orgs: Option>, + ) -> anyhow::Result> { + let mut repos = Vec::new(); + + if let Some(user) = user { + let mut r = self.gitea_client.get_user_repositories(&user).await?; + + repos.append(&mut r); + } + + if let Some(orgs) = orgs { + for org in orgs { + let mut r = self.gitea_client.get_org_repositories(&org).await?; + repos.append(&mut r); + } + } + + Ok(repos) + } +} + +pub trait ReconcilerState { + fn reconciler(&self) -> Reconciler; +} + +impl ReconcilerState for SharedState { + fn reconciler(&self) -> Reconciler { + Reconciler::new(self.gitea_client()) + } +} diff --git a/crates/contractor/src/state.rs b/crates/contractor/src/state.rs index c98c782..6323d49 100644 --- a/crates/contractor/src/state.rs +++ b/crates/contractor/src/state.rs @@ -1,5 +1,7 @@ use std::{ops::Deref, sync::Arc}; +use crate::services::gitea::GiteaClient; + #[derive(Clone)] pub struct SharedState(Arc); -- 2.45.2 From 33e6cd8a3aed535ffbcd0fac94df0d22308a1231 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Fri, 12 Apr 2024 16:23:04 +0200 Subject: [PATCH 35/74] feat: make sure to run a distinct first Signed-off-by: kjuulh --- Cargo.lock | 1 + crates/contractor/Cargo.toml | 1 + crates/contractor/src/services/gitea.rs | 3 +-- crates/contractor/src/services/reconciler.rs | 4 +++- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e2db86..04cc68a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -319,6 +319,7 @@ dependencies = [ "clap", "dotenv", "futures", + "itertools", "reqwest", "serde", "sqlx", diff --git a/crates/contractor/Cargo.toml b/crates/contractor/Cargo.toml index eeec02c..6bc08c7 100644 --- a/crates/contractor/Cargo.toml +++ b/crates/contractor/Cargo.toml @@ -18,3 +18,4 @@ uuid = { version = "1.7.0", features = ["v4"] } tower-http = { version = "0.5.2", features = ["cors", "trace"] } futures = "0.3.30" reqwest = {version = "0.12.3", default-features = false, features = ["json", "rustls-tls"]} +itertools = "0.12.1" diff --git a/crates/contractor/src/services/gitea.rs b/crates/contractor/src/services/gitea.rs index 2a164da..25bac0b 100644 --- a/crates/contractor/src/services/gitea.rs +++ b/crates/contractor/src/services/gitea.rs @@ -17,7 +17,7 @@ impl Deref for GiteaClient { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct Repository { pub owner: String, pub name: String, @@ -142,6 +142,5 @@ mod extensions; pub mod traits; use anyhow::Context; -use axum::http::HeaderMap; pub use extensions::*; use serde::Deserialize; diff --git a/crates/contractor/src/services/reconciler.rs b/crates/contractor/src/services/reconciler.rs index 458721c..63d8ab1 100644 --- a/crates/contractor/src/services/reconciler.rs +++ b/crates/contractor/src/services/reconciler.rs @@ -1,3 +1,5 @@ +use itertools::Itertools; + use crate::SharedState; use super::gitea::{GiteaClient, GiteaClientState, Repository}; @@ -43,7 +45,7 @@ impl Reconciler { } } - Ok(repos) + Ok(repos.into_iter().unique().collect()) } } -- 2.45.2 From 3709e37599347336bf122a01543d2d0c62a56c46 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Fri, 12 Apr 2024 16:44:32 +0200 Subject: [PATCH 36/74] feat: filter for those with renovate enabled Signed-off-by: kjuulh --- crates/contractor/src/main.rs | 6 +-- crates/contractor/src/services/gitea.rs | 37 +++++++++++++++++++ .../contractor/src/services/gitea/traits.rs | 5 +++ crates/contractor/src/services/reconciler.rs | 36 +++++++++++++++++- 4 files changed, 80 insertions(+), 4 deletions(-) diff --git a/crates/contractor/src/main.rs b/crates/contractor/src/main.rs index f93c5a5..cc133d7 100644 --- a/crates/contractor/src/main.rs +++ b/crates/contractor/src/main.rs @@ -22,7 +22,7 @@ enum Commands { #[arg(long)] user: Option, #[arg(long)] - orgs: Option>, + org: Option>, }, } @@ -61,12 +61,12 @@ async fn main() -> anyhow::Result<()> { result?? } } - Some(Commands::Reconcile { user, orgs }) => { + Some(Commands::Reconcile { user, org }) => { tracing::info!("running reconcile"); let state = SharedState::from(Arc::new(State::new().await?)); - state.reconciler().reconcile(user, orgs).await?; + state.reconciler().reconcile(user, org).await?; } None => {} } diff --git a/crates/contractor/src/services/gitea.rs b/crates/contractor/src/services/gitea.rs index 25bac0b..6c6bb0b 100644 --- a/crates/contractor/src/services/gitea.rs +++ b/crates/contractor/src/services/gitea.rs @@ -72,6 +72,7 @@ impl Default for DefaultGiteaClient { impl DefaultGiteaClient { pub async fn fetch_user_repos(&self) -> anyhow::Result> { + //FIXME: We should collect the pages for these queries let client = reqwest::Client::new(); let url = format!("{}/api/v1/user/repos", self.url); @@ -114,6 +115,32 @@ impl DefaultGiteaClient { .flat_map(Repository::try_from) .collect()) } + + async fn fetch_renovate(&self, repo: &Repository) -> anyhow::Result> { + let client = reqwest::Client::new(); + + let url = format!( + "{}/api/v1/repos/{}/{}/contents/renovate.json", + self.url, &repo.owner, &repo.name + ); + + tracing::trace!("calling url: {}", &url); + + let response = client + .get(&url) + .header("Content-Type", "application/json") + .header("Authorization", format!("token {}", self.token)) + .send() + .await?; + + match response.error_for_status() { + Ok(_) => Ok(Some(())), + Err(e) => match e.status() { + Some(StatusCode::NOT_FOUND) => Ok(None), + _ => anyhow::bail!(e), + }, + } + } } impl traits::GiteaClient for DefaultGiteaClient { @@ -136,6 +163,15 @@ impl traits::GiteaClient for DefaultGiteaClient { Box::pin(async move { self.fetch_org_repos(org).await }) } + + fn renovate_enabled<'a>( + &'a self, + repo: &'a Repository, + ) -> Pin> + Send + 'a>> { + tracing::trace!("checking whether renovate is enabled for: {:?}", repo); + + Box::pin(async { self.fetch_renovate(repo).await.map(|s| s.is_some()) }) + } } mod extensions; @@ -143,4 +179,5 @@ pub mod traits; use anyhow::Context; pub use extensions::*; +use reqwest::StatusCode; use serde::Deserialize; diff --git a/crates/contractor/src/services/gitea/traits.rs b/crates/contractor/src/services/gitea/traits.rs index 27daf5a..84efdc8 100644 --- a/crates/contractor/src/services/gitea/traits.rs +++ b/crates/contractor/src/services/gitea/traits.rs @@ -14,4 +14,9 @@ pub trait GiteaClient { &'a self, org: &'a str, ) -> Pin>> + Send + 'a>>; + + fn renovate_enabled<'a>( + &'a self, + repo: &'a Repository, + ) -> Pin> + Send + 'a>>; } diff --git a/crates/contractor/src/services/reconciler.rs b/crates/contractor/src/services/reconciler.rs index 63d8ab1..77fba4a 100644 --- a/crates/contractor/src/services/reconciler.rs +++ b/crates/contractor/src/services/reconciler.rs @@ -1,3 +1,4 @@ +use futures::{stream::FuturesUnordered, StreamExt}; use itertools::Itertools; use crate::SharedState; @@ -19,8 +20,13 @@ impl Reconciler { orgs: Option>, ) -> anyhow::Result<()> { let repos = self.get_repos(user, orgs).await?; + tracing::debug!("found repositories: {}", repos.len()); - tracing::info!("found repositories: {}", repos.len()); + let renovate_enabled = self.get_renovate_enabled(&repos).await?; + tracing::debug!( + "found repositories with renovate enabled: {}", + renovate_enabled.len() + ); Ok(()) } @@ -47,6 +53,34 @@ impl Reconciler { Ok(repos.into_iter().unique().collect()) } + + async fn get_renovate_enabled(&self, repos: &[Repository]) -> anyhow::Result> { + let mut futures = FuturesUnordered::new(); + + for repo in repos { + futures.push(async move { + let enabled = self.gitea_client.renovate_enabled(repo).await?; + + if enabled { + Ok::, anyhow::Error>(Some(repo.to_owned())) + } else { + tracing::trace!("repository: {:?}, doesn't have renovate enabled", repo); + Ok(None) + } + }) + } + + let mut enabled = Vec::new(); + while let Some(res) = futures.next().await { + let res = res?; + + if let Some(repo) = res { + enabled.push(repo) + } + } + + Ok(enabled) + } } pub trait ReconcilerState { -- 2.45.2 From 706a62a2926a06b6fe07ed4f9796fe60d46e23cc Mon Sep 17 00:00:00 2001 From: kjuulh Date: Fri, 12 Apr 2024 22:30:45 +0200 Subject: [PATCH 37/74] feat: add filter Signed-off-by: kjuulh --- Cargo.lock | 39 ++++++++++++++++++++ crates/contractor/Cargo.toml | 1 + crates/contractor/src/main.rs | 7 +++- crates/contractor/src/services/gitea.rs | 8 +++- crates/contractor/src/services/reconciler.rs | 30 ++++++++++++++- 5 files changed, 81 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 04cc68a..23d81de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,6 +30,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "allocator-api2" version = "0.2.18" @@ -320,6 +329,7 @@ dependencies = [ "dotenv", "futures", "itertools", + "regex", "reqwest", "serde", "sqlx", @@ -1240,6 +1250,35 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + [[package]] name = "reqwest" version = "0.12.3" diff --git a/crates/contractor/Cargo.toml b/crates/contractor/Cargo.toml index 6bc08c7..d80450f 100644 --- a/crates/contractor/Cargo.toml +++ b/crates/contractor/Cargo.toml @@ -19,3 +19,4 @@ tower-http = { version = "0.5.2", features = ["cors", "trace"] } futures = "0.3.30" reqwest = {version = "0.12.3", default-features = false, features = ["json", "rustls-tls"]} itertools = "0.12.1" +regex = "1.10.4" diff --git a/crates/contractor/src/main.rs b/crates/contractor/src/main.rs index cc133d7..d35415f 100644 --- a/crates/contractor/src/main.rs +++ b/crates/contractor/src/main.rs @@ -23,6 +23,9 @@ enum Commands { user: Option, #[arg(long)] org: Option>, + + #[arg(long, env = "CONTRACTOR_FILTER")] + filter: Option, }, } @@ -61,12 +64,12 @@ async fn main() -> anyhow::Result<()> { result?? } } - Some(Commands::Reconcile { user, org }) => { + Some(Commands::Reconcile { user, org, filter }) => { tracing::info!("running reconcile"); let state = SharedState::from(Arc::new(State::new().await?)); - state.reconciler().reconcile(user, org).await?; + state.reconciler().reconcile(user, org, filter).await?; } None => {} } diff --git a/crates/contractor/src/services/gitea.rs b/crates/contractor/src/services/gitea.rs index 6c6bb0b..81cb39e 100644 --- a/crates/contractor/src/services/gitea.rs +++ b/crates/contractor/src/services/gitea.rs @@ -1,4 +1,4 @@ -use std::{ops::Deref, pin::Pin, sync::Arc}; +use std::{fmt::Display, ops::Deref, pin::Pin, sync::Arc}; type DynGiteaClient = Arc; pub struct GiteaClient(DynGiteaClient); @@ -23,6 +23,12 @@ pub struct Repository { pub name: String, } +impl Display for Repository { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!("{}/{}", self.owner, self.name)) + } +} + impl TryFrom for Repository { type Error = anyhow::Error; diff --git a/crates/contractor/src/services/reconciler.rs b/crates/contractor/src/services/reconciler.rs index 77fba4a..5c0d65c 100644 --- a/crates/contractor/src/services/reconciler.rs +++ b/crates/contractor/src/services/reconciler.rs @@ -1,3 +1,4 @@ +use anyhow::Context; use futures::{stream::FuturesUnordered, StreamExt}; use itertools::Itertools; @@ -18,11 +19,38 @@ impl Reconciler { &self, user: Option, orgs: Option>, + filter: Option, ) -> anyhow::Result<()> { let repos = self.get_repos(user, orgs).await?; tracing::debug!("found repositories: {}", repos.len()); - let renovate_enabled = self.get_renovate_enabled(&repos).await?; + let filtered_repos = match filter { + Some(filter) => { + let re = regex::Regex::new(&filter).context( + "filter regex failed to compile, make sure it is valid against rust-lang/regex", + )?; + + repos + .into_iter() + .filter(|r| { + if re.is_match(&r.to_string()) { + true + } else { + tracing::trace!( + filter = &filter, + "repository: {}, didn't match filter", + r.to_string(), + ); + false + } + }) + .collect() + } + None => repos, + }; + tracing::debug!("filtered repositories: {}", filtered_repos.len()); + + let renovate_enabled = self.get_renovate_enabled(&filtered_repos).await?; tracing::debug!( "found repositories with renovate enabled: {}", renovate_enabled.len() -- 2.45.2 From ff81ab252ab4782d6083c528eb83e17f4d70a494 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Fri, 12 Apr 2024 23:32:10 +0200 Subject: [PATCH 38/74] feat: add ensure webhook Signed-off-by: kjuulh --- Cargo.lock | 1 + crates/contractor/Cargo.toml | 1 + crates/contractor/src/main.rs | 15 +- crates/contractor/src/services/gitea.rs | 184 +++++++++++++++++- .../contractor/src/services/gitea/traits.rs | 6 + crates/contractor/src/services/reconciler.rs | 30 +++ 6 files changed, 234 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 23d81de..e7b6117 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -332,6 +332,7 @@ dependencies = [ "regex", "reqwest", "serde", + "serde_json", "sqlx", "tokio", "tower-http", diff --git a/crates/contractor/Cargo.toml b/crates/contractor/Cargo.toml index d80450f..edde31c 100644 --- a/crates/contractor/Cargo.toml +++ b/crates/contractor/Cargo.toml @@ -20,3 +20,4 @@ futures = "0.3.30" reqwest = {version = "0.12.3", default-features = false, features = ["json", "rustls-tls"]} itertools = "0.12.1" regex = "1.10.4" +serde_json = "1.0.115" diff --git a/crates/contractor/src/main.rs b/crates/contractor/src/main.rs index d35415f..e2f513b 100644 --- a/crates/contractor/src/main.rs +++ b/crates/contractor/src/main.rs @@ -26,6 +26,9 @@ enum Commands { #[arg(long, env = "CONTRACTOR_FILTER")] filter: Option, + + #[arg(long = "force-refresh", env = "CONTRACTOR_FORCE_REFRESH")] + force_refresh: bool, }, } @@ -64,12 +67,20 @@ async fn main() -> anyhow::Result<()> { result?? } } - Some(Commands::Reconcile { user, org, filter }) => { + Some(Commands::Reconcile { + user, + org, + filter, + force_refresh, + }) => { tracing::info!("running reconcile"); let state = SharedState::from(Arc::new(State::new().await?)); - state.reconciler().reconcile(user, org, filter).await?; + state + .reconciler() + .reconcile(user, org, filter, force_refresh) + .await?; } None => {} } diff --git a/crates/contractor/src/services/gitea.rs b/crates/contractor/src/services/gitea.rs index 81cb39e..05ad799 100644 --- a/crates/contractor/src/services/gitea.rs +++ b/crates/contractor/src/services/gitea.rs @@ -76,6 +76,42 @@ impl Default for DefaultGiteaClient { } } +#[derive(Clone, Debug, Deserialize)] +pub struct GiteaWebhook { + id: isize, + #[serde(rename = "type")] + r#type: GiteaWebhookType, + config: GiteaWebhookConfig, +} +#[derive(Clone, Debug, Deserialize)] +pub struct GiteaWebhookConfig { + url: String, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +pub enum GiteaWebhookType { + #[serde(rename = "gitea")] + Gitea, + Other(String), +} + +#[derive(Clone, Debug, Serialize)] +pub struct CreateGiteaWebhook { + active: bool, + authorization_header: Option, + branch_filter: Option, + config: CreateGiteaWebhookConfig, + events: Vec, + #[serde(rename = "type")] + r#type: GiteaWebhookType, +} + +#[derive(Clone, Debug, Serialize)] +pub struct CreateGiteaWebhookConfig { + content_type: String, + url: String, +} + impl DefaultGiteaClient { pub async fn fetch_user_repos(&self) -> anyhow::Result> { //FIXME: We should collect the pages for these queries @@ -147,6 +183,126 @@ impl DefaultGiteaClient { }, } } + + async fn get_webhook(&self, repo: &Repository) -> anyhow::Result> { + let client = reqwest::Client::new(); + + let url = format!( + "{}/api/v1/repos/{}/{}/hooks", + self.url, &repo.owner, &repo.name + ); + + tracing::trace!("calling url: {}", &url); + + let response = client + .get(&url) + .header("Content-Type", "application/json") + .header("Authorization", format!("token {}", self.token)) + .send() + .await?; + + let webhooks = response.json::>().await?; + + let valid_webhooks = webhooks + .into_iter() + .filter(|w| w.r#type == GiteaWebhookType::Gitea) + .filter(|w| w.config.url.contains("contractor")) + .collect::>(); + + Ok(valid_webhooks.first().map(|f| f.to_owned())) + } + + async fn add_webhook(&self, repo: &Repository) -> anyhow::Result<()> { + let client = reqwest::Client::new(); + + let url = format!( + "{}/api/v1/repos/{}/{}/hooks", + self.url, &repo.owner, &repo.name + ); + + let val = CreateGiteaWebhook { + active: true, + authorization_header: Some("something".into()), + branch_filter: Some("*".into()), + config: CreateGiteaWebhookConfig { + content_type: "json".into(), + url: "https://url?type=contractor".into(), + }, + events: vec!["pull_request_review_comment".into()], + r#type: GiteaWebhookType::Gitea, + }; + + tracing::trace!( + "calling url: {} with body {}", + &url, + serde_json::to_string(&val)? + ); + + let response = client + .post(&url) + .header("Content-Type", "application/json") + .header("Accept", "application/json") + .header("Authorization", format!("token {}", self.token)) + .json(&val) + .send() + .await?; + + if let Err(e) = response.error_for_status_ref() { + if let Ok(ok) = response.text().await { + anyhow::bail!("failed to create webhook: {}, body: {}", e, ok); + } + + anyhow::bail!("failed to create webhook: {}", e) + } + + Ok(()) + } + + async fn update_webhook(&self, repo: &Repository, webhook: GiteaWebhook) -> anyhow::Result<()> { + let client = reqwest::Client::new(); + + let url = format!( + "{}/api/v1/repos/{}/{}/hooks/{}", + self.url, &repo.owner, &repo.name, &webhook.id, + ); + + let val = CreateGiteaWebhook { + active: true, + authorization_header: Some("something".into()), + branch_filter: Some("*".into()), + config: CreateGiteaWebhookConfig { + content_type: "json".into(), + url: "https://url?type=contractor".into(), + }, + events: vec!["pull_request_review_comment".into()], + r#type: GiteaWebhookType::Gitea, + }; + + tracing::trace!( + "calling url: {} with body {}", + &url, + serde_json::to_string(&val)? + ); + + let response = client + .patch(&url) + .header("Content-Type", "application/json") + .header("Accept", "application/json") + .header("Authorization", format!("token {}", self.token)) + .json(&val) + .send() + .await?; + + if let Err(e) = response.error_for_status_ref() { + if let Ok(ok) = response.text().await { + anyhow::bail!("failed to create webhook: {}, body: {}", e, ok); + } + + anyhow::bail!("failed to create webhook: {}", e) + } + + Ok(()) + } } impl traits::GiteaClient for DefaultGiteaClient { @@ -178,6 +334,32 @@ impl traits::GiteaClient for DefaultGiteaClient { Box::pin(async { self.fetch_renovate(repo).await.map(|s| s.is_some()) }) } + + fn ensure_webhook<'a>( + &'a self, + repo: &'a Repository, + force_refresh: bool, + ) -> Pin> + Send + 'a>> { + tracing::trace!("ensuring webhook exists for repo: {}", repo); + + Box::pin(async move { + match (self.get_webhook(repo).await?, force_refresh) { + (Some(_), false) => { + tracing::trace!("webhook already found for {} skipping...", repo); + } + (Some(webhook), true) => { + tracing::trace!("webhook already found for {} refreshing it", repo); + self.update_webhook(repo, webhook).await?; + } + (None, _) => { + tracing::trace!("webhook was not found for {} adding", repo); + self.add_webhook(repo).await?; + } + } + + Ok(()) + }) + } } mod extensions; @@ -186,4 +368,4 @@ pub mod traits; use anyhow::Context; pub use extensions::*; use reqwest::StatusCode; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; diff --git a/crates/contractor/src/services/gitea/traits.rs b/crates/contractor/src/services/gitea/traits.rs index 84efdc8..5394c40 100644 --- a/crates/contractor/src/services/gitea/traits.rs +++ b/crates/contractor/src/services/gitea/traits.rs @@ -19,4 +19,10 @@ pub trait GiteaClient { &'a self, repo: &'a Repository, ) -> Pin> + Send + 'a>>; + + fn ensure_webhook<'a>( + &'a self, + repo: &'a Repository, + force_refresh: bool, + ) -> Pin> + Send + 'a>>; } diff --git a/crates/contractor/src/services/reconciler.rs b/crates/contractor/src/services/reconciler.rs index 5c0d65c..cc1558b 100644 --- a/crates/contractor/src/services/reconciler.rs +++ b/crates/contractor/src/services/reconciler.rs @@ -20,6 +20,7 @@ impl Reconciler { user: Option, orgs: Option>, filter: Option, + force_refresh: bool, ) -> anyhow::Result<()> { let repos = self.get_repos(user, orgs).await?; tracing::debug!("found repositories: {}", repos.len()); @@ -56,6 +57,9 @@ impl Reconciler { renovate_enabled.len() ); + self.ensure_webhook(&renovate_enabled, force_refresh) + .await?; + Ok(()) } @@ -109,6 +113,32 @@ impl Reconciler { Ok(enabled) } + + async fn ensure_webhook( + &self, + repos: &[Repository], + force_refresh: bool, + ) -> anyhow::Result<()> { + tracing::debug!("ensuring webhooks are setup for repos"); + + let mut tasks = FuturesUnordered::new(); + + for repo in repos { + tasks.push(async move { + self.gitea_client + .ensure_webhook(repo, force_refresh) + .await?; + + Ok::<(), anyhow::Error>(()) + }) + } + + while let Some(res) = tasks.next().await { + res?; + } + + Ok(()) + } } pub trait ReconcilerState { -- 2.45.2 From 8d6e7062637ca25cbf029d43dd15e238da2803a8 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Fri, 12 Apr 2024 23:35:01 +0200 Subject: [PATCH 39/74] feat: add issues also Signed-off-by: kjuulh --- crates/contractor/src/services/gitea.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/contractor/src/services/gitea.rs b/crates/contractor/src/services/gitea.rs index 05ad799..c52a085 100644 --- a/crates/contractor/src/services/gitea.rs +++ b/crates/contractor/src/services/gitea.rs @@ -228,7 +228,7 @@ impl DefaultGiteaClient { content_type: "json".into(), url: "https://url?type=contractor".into(), }, - events: vec!["pull_request_review_comment".into()], + events: vec!["pull_request_comment".into(), "issue_comment".into()], r#type: GiteaWebhookType::Gitea, }; @@ -274,7 +274,7 @@ impl DefaultGiteaClient { content_type: "json".into(), url: "https://url?type=contractor".into(), }, - events: vec!["pull_request_review_comment".into()], + events: vec!["pull_request_comment".into(), "issue_comment".into()], r#type: GiteaWebhookType::Gitea, }; -- 2.45.2 From 2b095687b4c63a4e9c4516bc577cb2aa644a4916 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Sat, 13 Apr 2024 00:07:46 +0200 Subject: [PATCH 40/74] feat: add paging Signed-off-by: kjuulh --- crates/contractor/src/main.rs | 2 + crates/contractor/src/services/gitea.rs | 148 ++++++++++++++++++++---- 2 files changed, 128 insertions(+), 22 deletions(-) diff --git a/crates/contractor/src/main.rs b/crates/contractor/src/main.rs index e2f513b..4041ca8 100644 --- a/crates/contractor/src/main.rs +++ b/crates/contractor/src/main.rs @@ -81,6 +81,8 @@ async fn main() -> anyhow::Result<()> { .reconciler() .reconcile(user, org, filter, force_refresh) .await?; + + tracing::info!("done running reconcile"); } None => {} } diff --git a/crates/contractor/src/services/gitea.rs b/crates/contractor/src/services/gitea.rs index c52a085..2a39954 100644 --- a/crates/contractor/src/services/gitea.rs +++ b/crates/contractor/src/services/gitea.rs @@ -113,11 +113,13 @@ pub struct CreateGiteaWebhookConfig { } impl DefaultGiteaClient { - pub async fn fetch_user_repos(&self) -> anyhow::Result> { - //FIXME: We should collect the pages for these queries + async fn fetch_user_repos_page( + &self, + page: usize, + ) -> anyhow::Result<(Vec, Vec)> { let client = reqwest::Client::new(); - let url = format!("{}/api/v1/user/repos", self.url); + let url = format!("{}/api/v1/user/repos?page={page}&limit=50", self.url); tracing::trace!("calling url: {}", &url); @@ -128,34 +130,105 @@ impl DefaultGiteaClient { .send() .await?; + let mut pages = Vec::new(); + if page <= 1 { + if let Some(link_header) = response.headers().get("link") { + let link_str = link_header.to_str()?; + pages = parse_link(page, link_str)?; + } + } + let repositories = response.json::>().await?; - Ok(repositories - .into_iter() - .flat_map(Repository::try_from) - .collect()) + Ok(( + repositories + .into_iter() + .flat_map(Repository::try_from) + .collect(), + pages, + )) + } + + pub async fn fetch_user_repos(&self) -> anyhow::Result> { + let (mut repos, pages) = self.fetch_user_repos_page(1).await?; + + let mut tasks = FuturesUnordered::new(); + + for page in pages { + tasks.push(async move { + let (new_repos, _) = self.fetch_user_repos_page(page).await?; + + Ok::, anyhow::Error>(new_repos) + }) + } + + while let Some(new_repos) = tasks.next().await { + let mut new_repos = new_repos?; + repos.append(&mut new_repos); + } + + Ok(repos) + } + + async fn fetch_org_repos_page( + &self, + org: &str, + page: usize, + ) -> anyhow::Result<(Vec, Vec)> { + let client = reqwest::Client::new(); + + let url = format!( + "{}/api/v1/orgs/{}/repos?page={page}&limit=50", + self.url, org + ); + + tracing::trace!("calling url: {}", &url); + + let response = client + .get(&url) + .header("Content-Type", "application/json") + .header("Authorization", format!("token {}", self.token)) + .send() + .await?; + + let mut pages = Vec::new(); + if page <= 1 { + if let Some(link_header) = response.headers().get("link") { + let link_str = link_header.to_str()?; + pages = parse_link(page, link_str)?; + } + } + + let repositories = response.json::>().await?; + + Ok(( + repositories + .into_iter() + .flat_map(Repository::try_from) + .collect(), + pages, + )) } pub async fn fetch_org_repos(&self, org: &str) -> anyhow::Result> { - let client = reqwest::Client::new(); + let (mut repos, pages) = self.fetch_org_repos_page(org, 1).await?; - let url = format!("{}/api/v1/orgs/{}/repos", self.url, org); + let mut tasks = FuturesUnordered::new(); - tracing::trace!("calling url: {}", &url); + for page in pages { + tasks.push(async move { + let (new_repos, _) = self.fetch_org_repos_page(org, page).await?; - let response = client - .get(&url) - .header("Content-Type", "application/json") - .header("Authorization", format!("token {}", self.token)) - .send() - .await?; + Ok::, anyhow::Error>(new_repos) + }) + } - let repositories = response.json::>().await?; + while let Some(new_repos) = tasks.next().await { + let mut new_repos = new_repos?; + repos.append(&mut new_repos); + } - Ok(repositories - .into_iter() - .flat_map(Repository::try_from) - .collect()) + Ok(repos) } async fn fetch_renovate(&self, repo: &Repository) -> anyhow::Result> { @@ -362,10 +435,41 @@ impl traits::GiteaClient for DefaultGiteaClient { } } +// ; rel="next",; rel="last" +fn parse_link(page: usize, link_str: &str) -> anyhow::Result> { + let link_sections = link_str.split(','); + + for link_section in link_sections { + if let Some((link, rel)) = link_section.rsplit_once("; ") { + if rel == r#"rel="last""# { + let actual_link = &link[1..link.len() - 1]; + + let url = Url::parse(actual_link)?; + + if let Some(page_num) = url + .query_pairs() + .into_iter() + .find(|(name, _)| name == "page") + .map(|(_, value)| value) + { + let page_num: usize = page_num.parse()?; + + let page_numbers = (page + 1..page_num).collect::>(); + + return Ok(page_numbers); + } + } + } + } + + Ok(Vec::default()) +} + mod extensions; pub mod traits; use anyhow::Context; pub use extensions::*; -use reqwest::StatusCode; +use futures::{stream::FuturesUnordered, StreamExt}; +use reqwest::{StatusCode, Url}; use serde::{Deserialize, Serialize}; -- 2.45.2 From 7f732207537d75884e18e627f35688436e764ae6 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Sat, 13 Apr 2024 00:19:43 +0200 Subject: [PATCH 41/74] feat: make into stream instead Signed-off-by: kjuulh --- crates/contractor/src/services/gitea.rs | 41 +++++++++++-------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/crates/contractor/src/services/gitea.rs b/crates/contractor/src/services/gitea.rs index 2a39954..b531e94 100644 --- a/crates/contractor/src/services/gitea.rs +++ b/crates/contractor/src/services/gitea.rs @@ -150,24 +150,21 @@ impl DefaultGiteaClient { } pub async fn fetch_user_repos(&self) -> anyhow::Result> { - let (mut repos, pages) = self.fetch_user_repos_page(1).await?; + let (repos, pages) = self.fetch_user_repos_page(1).await?; - let mut tasks = FuturesUnordered::new(); - - for page in pages { - tasks.push(async move { + let tasks = pages + .into_iter() + .map(|page| async move { let (new_repos, _) = self.fetch_user_repos_page(page).await?; Ok::, anyhow::Error>(new_repos) }) - } + .collect::>(); - while let Some(new_repos) = tasks.next().await { - let mut new_repos = new_repos?; - repos.append(&mut new_repos); - } + let res: Result>, anyhow::Error> = tasks.try_collect().await; + let res = res?.into_iter().flatten(); - Ok(repos) + Ok(repos.into_iter().chain(res).collect()) } async fn fetch_org_repos_page( @@ -211,24 +208,21 @@ impl DefaultGiteaClient { } pub async fn fetch_org_repos(&self, org: &str) -> anyhow::Result> { - let (mut repos, pages) = self.fetch_org_repos_page(org, 1).await?; + let (repos, pages) = self.fetch_org_repos_page(org, 1).await?; - let mut tasks = FuturesUnordered::new(); - - for page in pages { - tasks.push(async move { + let tasks = pages + .into_iter() + .map(|page| async move { let (new_repos, _) = self.fetch_org_repos_page(org, page).await?; Ok::, anyhow::Error>(new_repos) }) - } + .collect::>(); - while let Some(new_repos) = tasks.next().await { - let mut new_repos = new_repos?; - repos.append(&mut new_repos); - } + let res: Result>, anyhow::Error> = tasks.try_collect().await; + let res = res?.into_iter().flatten(); - Ok(repos) + Ok(repos.into_iter().chain(res).collect()) } async fn fetch_renovate(&self, repo: &Repository) -> anyhow::Result> { @@ -470,6 +464,7 @@ pub mod traits; use anyhow::Context; pub use extensions::*; -use futures::{stream::FuturesUnordered, StreamExt}; +use futures::{stream::FuturesUnordered, StreamExt, TryStreamExt}; +use itertools::Itertools; use reqwest::{StatusCode, Url}; use serde::{Deserialize, Serialize}; -- 2.45.2 From fdda383f5a66df272e42306d4260d9c7b76be765 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Sat, 13 Apr 2024 01:17:09 +0200 Subject: [PATCH 42/74] feat: add bot Signed-off-by: kjuulh --- crates/contractor/src/api.rs | 106 +++++++++++++++++++++++- crates/contractor/src/schedule.rs | 2 - crates/contractor/src/services.rs | 1 + crates/contractor/src/services/bot.rs | 65 +++++++++++++++ crates/contractor/src/services/gitea.rs | 47 +++++------ 5 files changed, 191 insertions(+), 30 deletions(-) create mode 100644 crates/contractor/src/services/bot.rs diff --git a/crates/contractor/src/api.rs b/crates/contractor/src/api.rs index 192c9fd..91e6d02 100644 --- a/crates/contractor/src/api.rs +++ b/crates/contractor/src/api.rs @@ -1,15 +1,31 @@ -use std::net::SocketAddr; +use std::{net::SocketAddr, sync::Arc}; -use axum::{extract::MatchedPath, http::Request, routing::get, Router}; +use anyhow::Context; +use axum::{ + body::Body, + extract::{MatchedPath, State}, + http::Request, + response::IntoResponse, + routing::{get, post}, + Json, Router, +}; +use serde::{Deserialize, Serialize}; use tower_http::trace::TraceLayer; -use crate::SharedState; +use crate::{ + services::{ + bot::{BotRequest, BotState}, + gitea::Repository, + }, + SharedState, +}; pub async fn serve_axum(state: &SharedState, host: &SocketAddr) -> Result<(), anyhow::Error> { tracing::info!("running webhook server"); let app = Router::new() .route("/", get(root)) - .with_state(state.clone()) + .route("/webhooks/gitea", post(gitea_webhook)) + .with_state(state.to_owned()) .layer( TraceLayer::new_for_http().make_span_with(|request: &Request<_>| { // Log the matched route's path (with placeholders not filled in). @@ -38,3 +54,85 @@ pub async fn serve_axum(state: &SharedState, host: &SocketAddr) -> Result<(), an async fn root() -> &'static str { "Hello, contractor!" } + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct GiteaWebhookComment { + body: String, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct GiteaWebhookRepository { + full_name: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(untagged)] +pub enum GiteaWebhook { + Issue { + comment: GiteaWebhookComment, + repository: GiteaWebhookRepository, + }, +} + +pub enum ApiError { + InternalError(anyhow::Error), +} + +impl IntoResponse for ApiError { + fn into_response(self) -> axum::response::Response { + match self { + ApiError::InternalError(e) => { + tracing::error!("failed with internal error: {}", e); + + (axum::http::StatusCode::INTERNAL_SERVER_ERROR, e.to_string()) + } + } + .into_response() + } +} + +async fn gitea_webhook( + State(state): State, + Json(json): Json, +) -> Result { + tracing::info!( + "called: {}", + serde_json::to_string(&json) + .context("failed to serialize webhook") + .map_err(ApiError::InternalError)? + ); + + let bot_req: BotRequest = json.try_into().map_err(ApiError::InternalError)?; + + state + .bot() + .handle_request(bot_req) + .await + .map_err(ApiError::InternalError)?; + + Ok("Hello, contractor!") +} + +impl TryFrom for BotRequest { + type Error = anyhow::Error; + fn try_from(value: GiteaWebhook) -> Result { + match value { + GiteaWebhook::Issue { + comment, + repository, + } => { + let (owner, name) = repository.full_name.split_once('/').ok_or(anyhow::anyhow!( + "{} did not contain a valid owner/repository", + &repository.full_name + ))?; + + Ok(BotRequest { + repo: Repository { + owner: owner.into(), + name: name.into(), + }, + command: comment.body, + }) + } + } + } +} diff --git a/crates/contractor/src/schedule.rs b/crates/contractor/src/schedule.rs index 4cdad94..4fdbe15 100644 --- a/crates/contractor/src/schedule.rs +++ b/crates/contractor/src/schedule.rs @@ -7,8 +7,6 @@ pub async fn serve_cron_jobs(state: &SharedState) -> Result<(), anyhow::Error> { loop { tracing::info!("running cronjobs"); - todo!(); - tokio::time::sleep(std::time::Duration::from_secs(10_000)).await; } Ok::<(), anyhow::Error>(()) diff --git a/crates/contractor/src/services.rs b/crates/contractor/src/services.rs index 40a9bcd..6a96e7d 100644 --- a/crates/contractor/src/services.rs +++ b/crates/contractor/src/services.rs @@ -1,2 +1,3 @@ +pub mod bot; pub mod gitea; pub mod reconciler; diff --git a/crates/contractor/src/services/bot.rs b/crates/contractor/src/services/bot.rs new file mode 100644 index 0000000..5c42605 --- /dev/null +++ b/crates/contractor/src/services/bot.rs @@ -0,0 +1,65 @@ +use clap::{Parser, Subcommand}; + +use crate::SharedState; + +use super::gitea::Repository; + +pub struct Bot { + command_name: String, +} + +#[derive(Parser)] +#[command(author, version, about, long_about = None, subcommand_required = true)] +struct BotCommand { + #[command(subcommand)] + command: Option, +} + +#[derive(Subcommand)] +enum BotCommands { + Refresh { + #[arg(long)] + all: bool, + }, +} + +impl Bot { + pub fn new() -> Self { + Self { + command_name: std::env::var("CONTRACTOR_COMMAND_NAME").unwrap_or("contractor".into()), + } + } + + pub async fn handle_request(&self, req: impl Into) -> anyhow::Result<()> { + let req: BotRequest = req.into(); + + if !req.command.starts_with(&self.command_name) { + return Ok(()); + } + + let cmd = BotCommand::parse_from(req.command.split_whitespace()); + + match cmd.command { + Some(BotCommands::Refresh { all }) => { + tracing::info!("triggering refresh for: {}, all: {}", req.repo, all); + } + None => { + // TODO: Send back the help menu + } + } + + Ok(()) + } +} + +pub struct BotRequest { + pub repo: Repository, + pub command: String, +} + +pub trait BotState { + fn bot(&self) -> Bot { + Bot::new() + } +} +impl BotState for SharedState {} diff --git a/crates/contractor/src/services/gitea.rs b/crates/contractor/src/services/gitea.rs index b531e94..15a1ea9 100644 --- a/crates/contractor/src/services/gitea.rs +++ b/crates/contractor/src/services/gitea.rs @@ -60,6 +60,8 @@ pub struct GiteaRepository { pub struct DefaultGiteaClient { url: String, token: String, + + webhook_url: String, } impl Default for DefaultGiteaClient { @@ -72,6 +74,10 @@ impl Default for DefaultGiteaClient { token: std::env::var("GITEA_TOKEN") .context("GITEA_TOKEN should be set") .unwrap(), + webhook_url: std::env::var("CONTRACTOR_URL") + .context("CONTRACTOR_URL should be set") + .map(|url| format!("{}/webhooks/gitea", url.trim_end_matches('/'))) + .unwrap(), } } } @@ -287,17 +293,7 @@ impl DefaultGiteaClient { self.url, &repo.owner, &repo.name ); - let val = CreateGiteaWebhook { - active: true, - authorization_header: Some("something".into()), - branch_filter: Some("*".into()), - config: CreateGiteaWebhookConfig { - content_type: "json".into(), - url: "https://url?type=contractor".into(), - }, - events: vec!["pull_request_comment".into(), "issue_comment".into()], - r#type: GiteaWebhookType::Gitea, - }; + let val = self.create_webhook(); tracing::trace!( "calling url: {} with body {}", @@ -325,6 +321,20 @@ impl DefaultGiteaClient { Ok(()) } + fn create_webhook(&self) -> CreateGiteaWebhook { + CreateGiteaWebhook { + active: true, + authorization_header: Some("something".into()), + branch_filter: Some("*".into()), + config: CreateGiteaWebhookConfig { + content_type: "json".into(), + url: format!("{}?type=contractor", self.webhook_url), + }, + events: vec!["pull_request_comment".into(), "issue_comment".into()], + r#type: GiteaWebhookType::Gitea, + } + } + async fn update_webhook(&self, repo: &Repository, webhook: GiteaWebhook) -> anyhow::Result<()> { let client = reqwest::Client::new(); @@ -333,17 +343,7 @@ impl DefaultGiteaClient { self.url, &repo.owner, &repo.name, &webhook.id, ); - let val = CreateGiteaWebhook { - active: true, - authorization_header: Some("something".into()), - branch_filter: Some("*".into()), - config: CreateGiteaWebhookConfig { - content_type: "json".into(), - url: "https://url?type=contractor".into(), - }, - events: vec!["pull_request_comment".into(), "issue_comment".into()], - r#type: GiteaWebhookType::Gitea, - }; + let val = self.create_webhook(); tracing::trace!( "calling url: {} with body {}", @@ -464,7 +464,6 @@ pub mod traits; use anyhow::Context; pub use extensions::*; -use futures::{stream::FuturesUnordered, StreamExt, TryStreamExt}; -use itertools::Itertools; +use futures::{stream::FuturesUnordered, TryStreamExt}; use reqwest::{StatusCode, Url}; use serde::{Deserialize, Serialize}; -- 2.45.2 From 27a630d007104023db99e9786fb94355ee983b46 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Sat, 13 Apr 2024 12:45:05 +0200 Subject: [PATCH 43/74] feat: allow full run Signed-off-by: kjuulh --- Cargo.lock | 603 +++++++++++++++++- crates/contractor/Cargo.toml | 1 + crates/contractor/src/api.rs | 3 +- crates/contractor/src/schedule.rs | 5 +- crates/contractor/src/services.rs | 2 + crates/contractor/src/services/bot.rs | 29 +- crates/contractor/src/services/engines.rs | 1 + .../contractor/src/services/engines/dagger.rs | 157 +++++ crates/contractor/src/services/renovate.rs | 3 + crates/contractor/src/state.rs | 7 +- 10 files changed, 773 insertions(+), 38 deletions(-) create mode 100644 crates/contractor/src/services/engines.rs create mode 100644 crates/contractor/src/services/engines/dagger.rs create mode 100644 crates/contractor/src/services/renovate.rs diff --git a/Cargo.lock b/Cargo.lock index e7b6117..76f4322 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,6 +99,12 @@ version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +[[package]] +name = "ascii" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" + [[package]] name = "async-trait" version = "0.1.80" @@ -135,10 +141,10 @@ dependencies = [ "axum-core", "bytes", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.0", "http-body-util", - "hyper", + "hyper 1.2.0", "hyper-util", "itoa", "matchit", @@ -168,8 +174,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.0", "http-body-util", "mime", "pin-project-lite", @@ -286,7 +292,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", ] [[package]] @@ -313,6 +319,19 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "combine" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" +dependencies = [ + "ascii", + "byteorder", + "either", + "memchr", + "unreachable", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -326,11 +345,12 @@ dependencies = [ "anyhow", "axum", "clap", + "dagger-sdk", "dotenv", "futures", "itertools", "regex", - "reqwest", + "reqwest 0.12.3", "serde", "serde_json", "sqlx", @@ -341,6 +361,22 @@ dependencies = [ "uuid", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + [[package]] name = "cpufeatures" version = "0.2.12" @@ -365,6 +401,15 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-queue" version = "0.3.11" @@ -390,6 +435,70 @@ dependencies = [ "typenum", ] +[[package]] +name = "dagger-sdk" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79bc59868e62ea1451f158aeb8fbb36c5dd2fb098f31bf408dbd165251674edf" +dependencies = [ + "async-trait", + "base64 0.21.7", + "derive_builder", + "dirs", + "eyre", + "flate2", + "futures", + "graphql_client", + "hex", + "hex-literal", + "platform-info", + "reqwest 0.11.27", + "serde", + "serde_json", + "sha2", + "tar", + "tempfile", + "thiserror", + "tokio", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + [[package]] name = "der" version = "0.7.9" @@ -410,6 +519,37 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "derive_builder" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_macro" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" +dependencies = [ + "derive_builder_core", + "syn 1.0.109", +] + [[package]] name = "digest" version = "0.10.7" @@ -422,6 +562,27 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + [[package]] name = "dotenv" version = "0.15.0" @@ -443,6 +604,15 @@ dependencies = [ "serde", ] +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -476,18 +646,50 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + [[package]] name = "fastrand" version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +[[package]] +name = "filetime" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "windows-sys 0.52.0", +] + [[package]] name = "finl_unicode" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "flume" version = "0.11.0" @@ -641,6 +843,84 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "graphql-introspection-query" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2a4732cf5140bd6c082434494f785a19cfb566ab07d1382c3671f5812fed6d" +dependencies = [ + "serde", +] + +[[package]] +name = "graphql-parser" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ebc8013b4426d5b81a4364c419a95ed0b404af2b82e2457de52d9348f0e474" +dependencies = [ + "combine", + "thiserror", +] + +[[package]] +name = "graphql_client" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cdf7b487d864c2939b23902291a5041bc4a84418268f25fda1c8d4e15ad8fa" +dependencies = [ + "graphql_query_derive", + "reqwest 0.11.27", + "serde", + "serde_json", +] + +[[package]] +name = "graphql_client_codegen" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a40f793251171991c4eb75bd84bc640afa8b68ff6907bc89d3b712a22f700506" +dependencies = [ + "graphql-introspection-query", + "graphql-parser", + "heck 0.4.1", + "lazy_static", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn 1.0.109", +] + +[[package]] +name = "graphql_query_derive" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00bda454f3d313f909298f626115092d348bc231025699f557b27e248475f48c" +dependencies = [ + "graphql_client_codegen", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -687,6 +967,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + [[package]] name = "hkdf" version = "0.12.4" @@ -714,6 +1000,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http" version = "1.1.0" @@ -725,6 +1022,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + [[package]] name = "http-body" version = "1.0.0" @@ -732,7 +1040,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", - "http", + "http 1.1.0", ] [[package]] @@ -743,8 +1051,8 @@ checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" dependencies = [ "bytes", "futures-core", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -760,6 +1068,30 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + [[package]] name = "hyper" version = "1.2.0" @@ -769,8 +1101,8 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.0", "httparse", "httpdate", "itoa", @@ -780,6 +1112,20 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper 0.14.28", + "rustls 0.21.10", + "tokio", + "tokio-rustls 0.24.1", +] + [[package]] name = "hyper-rustls" version = "0.26.0" @@ -787,13 +1133,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ "futures-util", - "http", - "hyper", + "http 1.1.0", + "hyper 1.2.0", "hyper-util", "rustls 0.22.3", "rustls-pki-types", "tokio", - "tokio-rustls", + "tokio-rustls 0.25.0", "tower-service", ] @@ -806,9 +1152,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http", - "http-body", - "hyper", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.2.0", "pin-project-lite", "socket2", "tokio", @@ -817,6 +1163,12 @@ dependencies = [ "tracing", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.5.0" @@ -827,6 +1179,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + [[package]] name = "indexmap" version = "2.2.6" @@ -888,6 +1246,16 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.5.0", + "libc", +] + [[package]] name = "libsqlite3-sys" version = "0.27.0" @@ -1073,6 +1441,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "overload" version = "0.1.1" @@ -1182,6 +1556,16 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "platform-info" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5ff316b9c4642feda973c18f0decd6c8b0919d4722566f6e4337cce0dd88217" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -1251,6 +1635,17 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_users" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + [[package]] name = "regex" version = "1.10.4" @@ -1280,6 +1675,49 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.28", + "hyper-rustls 0.24.2", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.21.10", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 0.1.2", + "system-configuration", + "tokio", + "tokio-rustls 0.24.1", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots 0.25.4", + "winreg 0.50.0", +] + [[package]] name = "reqwest" version = "0.12.3" @@ -1290,11 +1728,11 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.0", "http-body-util", - "hyper", - "hyper-rustls", + "hyper 1.2.0", + "hyper-rustls 0.26.0", "hyper-util", "ipnet", "js-sys", @@ -1311,14 +1749,14 @@ dependencies = [ "serde_urlencoded", "sync_wrapper 0.1.2", "tokio", - "tokio-rustls", + "tokio-rustls 0.25.0", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", "webpki-roots 0.26.1", - "winreg", + "winreg 0.52.0", ] [[package]] @@ -1381,6 +1819,7 @@ version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ + "log", "ring", "rustls-webpki 0.101.7", "sct", @@ -1854,6 +2293,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "strsim" version = "0.11.1" @@ -1900,6 +2345,38 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tar" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +dependencies = [ + "filetime", + "libc", + "xattr", +] + [[package]] name = "tempfile" version = "3.10.1" @@ -2018,6 +2495,16 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.10", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.25.0" @@ -2040,6 +2527,20 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + [[package]] name = "tower" version = "0.4.13" @@ -2064,8 +2565,8 @@ checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ "bitflags 2.5.0", "bytes", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.0", "http-body-util", "pin-project-lite", "tower-layer", @@ -2139,6 +2640,7 @@ dependencies = [ "sharded-slab", "smallvec", "thread_local", + "tracing", "tracing-core", "tracing-log", ] @@ -2188,6 +2690,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +dependencies = [ + "void", +] + [[package]] name = "untrusted" version = "0.9.0" @@ -2244,6 +2755,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + [[package]] name = "want" version = "0.3.1" @@ -2331,6 +2848,19 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +[[package]] +name = "wasm-streams" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "web-sys" version = "0.3.69" @@ -2520,6 +3050,16 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "winreg" version = "0.52.0" @@ -2530,6 +3070,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys", + "rustix", +] + [[package]] name = "zerocopy" version = "0.7.32" diff --git a/crates/contractor/Cargo.toml b/crates/contractor/Cargo.toml index edde31c..8485f4f 100644 --- a/crates/contractor/Cargo.toml +++ b/crates/contractor/Cargo.toml @@ -21,3 +21,4 @@ reqwest = {version = "0.12.3", default-features = false, features = ["json", "ru itertools = "0.12.1" regex = "1.10.4" serde_json = "1.0.115" +dagger-sdk = "0.9.8" diff --git a/crates/contractor/src/api.rs b/crates/contractor/src/api.rs index 91e6d02..f7dc343 100644 --- a/crates/contractor/src/api.rs +++ b/crates/contractor/src/api.rs @@ -1,8 +1,7 @@ -use std::{net::SocketAddr, sync::Arc}; +use std::net::SocketAddr; use anyhow::Context; use axum::{ - body::Body, extract::{MatchedPath, State}, http::Request, response::IntoResponse, diff --git a/crates/contractor/src/schedule.rs b/crates/contractor/src/schedule.rs index 4fdbe15..204e652 100644 --- a/crates/contractor/src/schedule.rs +++ b/crates/contractor/src/schedule.rs @@ -1,9 +1,8 @@ -use crate::{services::gitea::GiteaClientState, SharedState}; +use crate::SharedState; pub async fn serve_cron_jobs(state: &SharedState) -> Result<(), anyhow::Error> { - let state = state.clone(); + let _state = state.clone(); tokio::spawn(async move { - let gitea_client = state.gitea_client(); loop { tracing::info!("running cronjobs"); diff --git a/crates/contractor/src/services.rs b/crates/contractor/src/services.rs index 6a96e7d..65b89f0 100644 --- a/crates/contractor/src/services.rs +++ b/crates/contractor/src/services.rs @@ -1,3 +1,5 @@ pub mod bot; +pub mod engines; pub mod gitea; pub mod reconciler; +pub mod renovate; diff --git a/crates/contractor/src/services/bot.rs b/crates/contractor/src/services/bot.rs index 5c42605..52b506b 100644 --- a/crates/contractor/src/services/bot.rs +++ b/crates/contractor/src/services/bot.rs @@ -1,11 +1,13 @@ use clap::{Parser, Subcommand}; -use crate::SharedState; +use crate::{services::renovate::RenovateConfig, SharedState}; -use super::gitea::Repository; +use super::{engines::dagger::Dagger, gitea::Repository}; pub struct Bot { command_name: String, + + dagger: Dagger, } #[derive(Parser)] @@ -24,9 +26,11 @@ enum BotCommands { } impl Bot { - pub fn new() -> Self { + pub fn new(dagger: Dagger) -> Self { Self { command_name: std::env::var("CONTRACTOR_COMMAND_NAME").unwrap_or("contractor".into()), + + dagger, } } @@ -42,6 +46,19 @@ impl Bot { match cmd.command { Some(BotCommands::Refresh { all }) => { tracing::info!("triggering refresh for: {}, all: {}", req.repo, all); + + let dagger = self.dagger.clone(); + tokio::spawn(async move { + match dagger + .execute_renovate(&RenovateConfig { + repo: format!("{}/{}", &req.repo.owner, &req.repo.name), + }) + .await + { + Ok(_) => {} + Err(e) => tracing::error!("failed to execute renovate: {}", e), + }; + }); } None => { // TODO: Send back the help menu @@ -58,8 +75,10 @@ pub struct BotRequest { } pub trait BotState { + fn bot(&self) -> Bot; +} +impl BotState for SharedState { fn bot(&self) -> Bot { - Bot::new() + Bot::new(self.engine.clone()) } } -impl BotState for SharedState {} diff --git a/crates/contractor/src/services/engines.rs b/crates/contractor/src/services/engines.rs new file mode 100644 index 0000000..6c02dba --- /dev/null +++ b/crates/contractor/src/services/engines.rs @@ -0,0 +1 @@ +pub mod dagger; diff --git a/crates/contractor/src/services/engines/dagger.rs b/crates/contractor/src/services/engines/dagger.rs new file mode 100644 index 0000000..be78ab6 --- /dev/null +++ b/crates/contractor/src/services/engines/dagger.rs @@ -0,0 +1,157 @@ +use std::{str::FromStr, sync::Arc}; + +use dagger_sdk::ContainerWithNewFileOptsBuilder; +use futures::Future; +use tokio::sync::RwLock; + +type DynDagger = Arc; + +#[derive(Clone)] +pub struct Dagger { + dagger: DynDagger, +} + +impl Default for Dagger { + fn default() -> Self { + Self::new() + } +} + +impl Dagger { + pub fn new() -> Self { + Self { + dagger: Arc::new(DefaultDagger::new()), + } + } +} + +impl std::ops::Deref for Dagger { + type Target = DynDagger; + + fn deref(&self) -> &Self::Target { + &self.dagger + } +} + +struct DefaultDagger { + client: Arc>>, +} + +impl DefaultDagger { + pub fn new() -> Self { + let client = Arc::new(RwLock::new(None)); + + let host = + std::env::var("CONTRACTOR_DOCKER_HOST").expect("CONTRACTOR_DOCKER_HOST to be set"); + + std::env::set_var("DOCKER_HOST", host); + + tokio::spawn({ + let client = client.clone(); + + async move { + let mut client = client.write().await; + + match dagger_sdk::connect().await { + Ok(o) => *client = Some(o), + Err(e) => tracing::error!("failed to start dagger engine: {}", e), + }; + } + }); + + Self { client } + } + + pub async fn get_client(&self) -> dagger_sdk::Query { + let client = self.client.clone().read().await.clone(); + + client.unwrap() + } +} + +impl traits::Dagger for DefaultDagger { + fn execute_renovate<'a>( + &'a self, + config: &'a crate::services::renovate::RenovateConfig, + ) -> std::pin::Pin> + Send + 'a>> { + Box::pin(async move { + let renovate_image = "renovate/renovate:37"; + + let client = self.get_client().await; + + let github_com_token = client.set_secret( + "GITHUB_COM_TOKEN", + std::env::var("CONTRACTOR_GITHUB_COM_TOKEN") + .expect("CONTRACTOR_GITHUB_COM_TOKEN to be set"), + ); + + let renovate_secrets = client.set_secret( + "RENOVATE_SECRETS", + std::env::var("CONTRACTOR_RENOVATE_SECRETS") + .expect("CONTRACTOR_RENOVATE_SECRETS to be set"), + ); + + let renovate_token = client.set_secret( + "RENOVATE_TOKEN", + std::env::var("CONTRACTOR_RENOVATE_TOKEN") + .expect("CONTRACTOR_RENOVATE_TOKEN to be set"), + ); + + let renovate_file_url = std::env::var("CONTRACTOR_RENOVATE_CONFIG_URL") + .expect("CONTRACTOR_RENOVATE_CONFIG_URL to be set"); + + let renovate_file = client.http(renovate_file_url).contents().await?; + + let mut renovate_file_value: serde_json::Value = serde_json::from_str(&renovate_file)?; + let obj = renovate_file_value + .as_object_mut() + .ok_or(anyhow::anyhow!("config is not a valid json object"))?; + + let _ = obj.insert("autodiscover".into(), serde_json::Value::from_str("false")?); + + let renovate_file = serde_json::to_string(&obj)?; + + let output = client + .container() + .from(renovate_image) + .with_secret_variable("GITHUB_COM_TOKEN", github_com_token) + .with_secret_variable("RENOVATE_SECRETS", renovate_secrets) + .with_secret_variable("RENOVATE_TOKEN", renovate_token) + .with_env_variable("LOG_LEVEL", "info") + .with_env_variable("RENOVATE_CONFIG_FILE", "/opt/renovate/config.json") + .with_new_file_opts( + "/opt/renovate/config.json", + ContainerWithNewFileOptsBuilder::default() + .contents(renovate_file.as_str()) + .permissions(0o644isize) + .build()?, + ) + .with_exec(vec![&config.repo]) + .stdout() + .await?; + + tracing::debug!( + "renovate on: {} finished with output {}", + &config.repo, + &output + ); + + Ok::<(), anyhow::Error>(()) + }) + } +} + +pub mod traits { + use std::pin::Pin; + + use futures::Future; + + use crate::services::renovate::RenovateConfig; + + pub trait Dagger { + fn execute_renovate<'a>( + &'a self, + config: &'a RenovateConfig, + ) -> Pin> + Send + 'a>>; + } +} diff --git a/crates/contractor/src/services/renovate.rs b/crates/contractor/src/services/renovate.rs new file mode 100644 index 0000000..ccc2c88 --- /dev/null +++ b/crates/contractor/src/services/renovate.rs @@ -0,0 +1,3 @@ +pub struct RenovateConfig { + pub repo: String, +} diff --git a/crates/contractor/src/state.rs b/crates/contractor/src/state.rs index 6323d49..ab6e05f 100644 --- a/crates/contractor/src/state.rs +++ b/crates/contractor/src/state.rs @@ -1,6 +1,6 @@ use std::{ops::Deref, sync::Arc}; -use crate::services::gitea::GiteaClient; +use crate::services::engines::dagger::Dagger; #[derive(Clone)] pub struct SharedState(Arc); @@ -21,6 +21,7 @@ impl Deref for SharedState { pub struct State { // pub db: Pool, + pub engine: Dagger, } impl State { @@ -38,6 +39,8 @@ impl State { // let _ = sqlx::query("SELECT 1;").fetch_one(&db).await?; // Ok(Self { db }) - Ok(Self {}) + let engine = Dagger::new(); + + Ok(Self { engine }) } } -- 2.45.2 From 6789e3f14a6848abccc4a4a87f1e4fa5cdb21dee Mon Sep 17 00:00:00 2001 From: kjuulh Date: Sat, 13 Apr 2024 13:27:20 +0200 Subject: [PATCH 44/74] feat: add backoff Signed-off-by: kjuulh --- Cargo.lock | 13 +++ crates/contractor/Cargo.toml | 1 + crates/contractor/src/services/gitea.rs | 97 ++++++++++++++------ crates/contractor/src/services/reconciler.rs | 1 + 4 files changed, 83 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76f4322..ab8b344 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -186,6 +186,18 @@ dependencies = [ "tracing", ] +[[package]] +name = "backon" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d67782c3f868daa71d3533538e98a8e13713231969def7536e8039606fc46bf0" +dependencies = [ + "fastrand", + "futures-core", + "pin-project", + "tokio", +] + [[package]] name = "backtrace" version = "0.3.71" @@ -344,6 +356,7 @@ version = "0.1.0" dependencies = [ "anyhow", "axum", + "backon", "clap", "dagger-sdk", "dotenv", diff --git a/crates/contractor/Cargo.toml b/crates/contractor/Cargo.toml index 8485f4f..f27ec4e 100644 --- a/crates/contractor/Cargo.toml +++ b/crates/contractor/Cargo.toml @@ -22,3 +22,4 @@ itertools = "0.12.1" regex = "1.10.4" serde_json = "1.0.115" dagger-sdk = "0.9.8" +backon = "0.4.4" diff --git a/crates/contractor/src/services/gitea.rs b/crates/contractor/src/services/gitea.rs index 15a1ea9..319b997 100644 --- a/crates/contractor/src/services/gitea.rs +++ b/crates/contractor/src/services/gitea.rs @@ -241,18 +241,35 @@ impl DefaultGiteaClient { tracing::trace!("calling url: {}", &url); - let response = client - .get(&url) - .header("Content-Type", "application/json") - .header("Authorization", format!("token {}", self.token)) - .send() - .await?; + let response = (|| async { + client + .get(&url) + .header("Content-Type", "application/json") + .header("Authorization", format!("token {}", self.token)) + .send() + .await + }) + .retry(&ExponentialBuilder::default()) + .notify(|err, dur| { + tracing::debug!("retrying job: {err}, in: {} seconds", dur.as_secs()); + }) + .await?; match response.error_for_status() { Ok(_) => Ok(Some(())), Err(e) => match e.status() { Some(StatusCode::NOT_FOUND) => Ok(None), - _ => anyhow::bail!(e), + Some(status) => { + tracing::warn!( + "failed to call fetch renovate for: {}, with error: {}", + &repo, + status + ); + anyhow::bail!(e) + } + _ => { + anyhow::bail!(e) + } }, } } @@ -267,12 +284,19 @@ impl DefaultGiteaClient { tracing::trace!("calling url: {}", &url); - let response = client - .get(&url) - .header("Content-Type", "application/json") - .header("Authorization", format!("token {}", self.token)) - .send() - .await?; + let response = (|| async { + client + .get(&url) + .header("Content-Type", "application/json") + .header("Authorization", format!("token {}", self.token)) + .send() + .await + }) + .retry(&ExponentialBuilder::default()) + .notify(|err, dur| { + tracing::debug!("retrying job: {err}, in: {} seconds", dur.as_secs()); + }) + .await?; let webhooks = response.json::>().await?; @@ -301,14 +325,21 @@ impl DefaultGiteaClient { serde_json::to_string(&val)? ); - let response = client - .post(&url) - .header("Content-Type", "application/json") - .header("Accept", "application/json") - .header("Authorization", format!("token {}", self.token)) - .json(&val) - .send() - .await?; + let response = (|| async { + client + .post(&url) + .header("Content-Type", "application/json") + .header("Accept", "application/json") + .header("Authorization", format!("token {}", self.token)) + .json(&val) + .send() + .await + }) + .retry(&ExponentialBuilder::default()) + .notify(|err, dur| { + tracing::debug!("retrying job: {err}, in: {} seconds", dur.as_secs()); + }) + .await?; if let Err(e) = response.error_for_status_ref() { if let Ok(ok) = response.text().await { @@ -351,14 +382,21 @@ impl DefaultGiteaClient { serde_json::to_string(&val)? ); - let response = client - .patch(&url) - .header("Content-Type", "application/json") - .header("Accept", "application/json") - .header("Authorization", format!("token {}", self.token)) - .json(&val) - .send() - .await?; + let response = (|| async { + client + .patch(&url) + .header("Content-Type", "application/json") + .header("Accept", "application/json") + .header("Authorization", format!("token {}", self.token)) + .json(&val) + .send() + .await + }) + .retry(&ExponentialBuilder::default()) + .notify(|err, dur| { + tracing::debug!("retrying job: {err}, in: {} seconds", dur.as_secs()); + }) + .await?; if let Err(e) = response.error_for_status_ref() { if let Ok(ok) = response.text().await { @@ -463,6 +501,7 @@ mod extensions; pub mod traits; use anyhow::Context; +use backon::{ExponentialBuilder, Retryable}; pub use extensions::*; use futures::{stream::FuturesUnordered, TryStreamExt}; use reqwest::{StatusCode, Url}; diff --git a/crates/contractor/src/services/reconciler.rs b/crates/contractor/src/services/reconciler.rs index cc1558b..51ac9c0 100644 --- a/crates/contractor/src/services/reconciler.rs +++ b/crates/contractor/src/services/reconciler.rs @@ -103,6 +103,7 @@ impl Reconciler { } let mut enabled = Vec::new(); + while let Some(res) = futures.next().await { let res = res?; -- 2.45.2 From 4129b15594d76cbf4842993a59ba5bc962a04d52 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Sun, 14 Apr 2024 13:40:33 +0000 Subject: [PATCH 45/74] fix(deps): update all dependencies --- crates/contractor/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/contractor/Cargo.toml b/crates/contractor/Cargo.toml index f27ec4e..6f7b05e 100644 --- a/crates/contractor/Cargo.toml +++ b/crates/contractor/Cargo.toml @@ -13,8 +13,8 @@ dotenv.workspace = true axum.workspace = true serde = { version = "1.0.197", features = ["derive"] } -sqlx = { version = "0.7.3", features = ["runtime-tokio", "tls-rustls", "postgres", "uuid", "time"] } -uuid = { version = "1.7.0", features = ["v4"] } +sqlx = { version = "0.7.4", features = ["runtime-tokio", "tls-rustls", "postgres", "uuid", "time"] } +uuid = { version = "1.8.0", features = ["v4"] } tower-http = { version = "0.5.2", features = ["cors", "trace"] } futures = "0.3.30" reqwest = {version = "0.12.3", default-features = false, features = ["json", "rustls-tls"]} -- 2.45.2 From fe49f0209f02e2ff2e577661467b2da53b4b885e Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Tue, 16 Apr 2024 06:14:28 +0000 Subject: [PATCH 46/74] fix(deps): update rust crate serde_json to 1.0.116 --- Cargo.lock | 4 ++-- crates/contractor/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab8b344..04abb96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1948,9 +1948,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ "itoa", "ryu", diff --git a/crates/contractor/Cargo.toml b/crates/contractor/Cargo.toml index 6f7b05e..6b25e24 100644 --- a/crates/contractor/Cargo.toml +++ b/crates/contractor/Cargo.toml @@ -20,6 +20,6 @@ futures = "0.3.30" reqwest = {version = "0.12.3", default-features = false, features = ["json", "rustls-tls"]} itertools = "0.12.1" regex = "1.10.4" -serde_json = "1.0.115" +serde_json = "1.0.116" dagger-sdk = "0.9.8" backon = "0.4.4" -- 2.45.2 From 5e9ac0c5f3fdbd33e0d3c11102302e28748759a5 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Tue, 16 Apr 2024 22:06:41 +0000 Subject: [PATCH 47/74] fix(deps): update rust crate serde to 1.0.198 --- Cargo.lock | 8 ++++---- crates/contractor/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 04abb96..6c7e246 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1928,18 +1928,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.197" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" dependencies = [ "proc-macro2", "quote", diff --git a/crates/contractor/Cargo.toml b/crates/contractor/Cargo.toml index 6b25e24..22c1bf4 100644 --- a/crates/contractor/Cargo.toml +++ b/crates/contractor/Cargo.toml @@ -12,7 +12,7 @@ clap.workspace = true dotenv.workspace = true axum.workspace = true -serde = { version = "1.0.197", features = ["derive"] } +serde = { version = "1.0.198", features = ["derive"] } sqlx = { version = "0.7.4", features = ["runtime-tokio", "tls-rustls", "postgres", "uuid", "time"] } uuid = { version = "1.8.0", features = ["v4"] } tower-http = { version = "0.5.2", features = ["cors", "trace"] } -- 2.45.2 From 8219ea0f2691d0faddb2b5d7c5b9d08df2746e10 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Fri, 19 Apr 2024 18:35:15 +0000 Subject: [PATCH 48/74] fix(deps): update rust crate reqwest to 0.12.4 --- Cargo.lock | 6 +++--- crates/contractor/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6c7e246..73c0d7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -363,7 +363,7 @@ dependencies = [ "futures", "itertools", "regex", - "reqwest 0.12.3", + "reqwest 0.12.4", "serde", "serde_json", "sqlx", @@ -1733,9 +1733,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e6cc1e89e689536eb5aeede61520e874df5a4707df811cd5da4aa5fbb2aae19" +checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" dependencies = [ "base64 0.22.0", "bytes", diff --git a/crates/contractor/Cargo.toml b/crates/contractor/Cargo.toml index 22c1bf4..9d7ed45 100644 --- a/crates/contractor/Cargo.toml +++ b/crates/contractor/Cargo.toml @@ -17,7 +17,7 @@ sqlx = { version = "0.7.4", features = ["runtime-tokio", "tls-rustls", "postgres uuid = { version = "1.8.0", features = ["v4"] } tower-http = { version = "0.5.2", features = ["cors", "trace"] } futures = "0.3.30" -reqwest = {version = "0.12.3", default-features = false, features = ["json", "rustls-tls"]} +reqwest = {version = "0.12.4", default-features = false, features = ["json", "rustls-tls"]} itertools = "0.12.1" regex = "1.10.4" serde_json = "1.0.116" -- 2.45.2 From baad43d545bc98feb9d832cbbccb9196f065f381 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Sat, 27 Apr 2024 05:10:56 +0000 Subject: [PATCH 49/74] fix(deps): update rust crate serde to 1.0.199 --- Cargo.lock | 8 ++++---- crates/contractor/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73c0d7b..9731d20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1928,18 +1928,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.198" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" +checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.198" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" +checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc" dependencies = [ "proc-macro2", "quote", diff --git a/crates/contractor/Cargo.toml b/crates/contractor/Cargo.toml index 9d7ed45..8e81d2c 100644 --- a/crates/contractor/Cargo.toml +++ b/crates/contractor/Cargo.toml @@ -12,7 +12,7 @@ clap.workspace = true dotenv.workspace = true axum.workspace = true -serde = { version = "1.0.198", features = ["derive"] } +serde = { version = "1.0.199", features = ["derive"] } sqlx = { version = "0.7.4", features = ["runtime-tokio", "tls-rustls", "postgres", "uuid", "time"] } uuid = { version = "1.8.0", features = ["v4"] } tower-http = { version = "0.5.2", features = ["cors", "trace"] } -- 2.45.2 From b09d7d2a2fa1c0f1b4e31f9628f283d917091477 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Wed, 1 May 2024 16:42:21 +0000 Subject: [PATCH 50/74] fix(deps): update rust crate serde to 1.0.200 --- Cargo.lock | 8 ++++---- crates/contractor/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9731d20..00810a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1928,18 +1928,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.199" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a" +checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.199" +version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc" +checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" dependencies = [ "proc-macro2", "quote", diff --git a/crates/contractor/Cargo.toml b/crates/contractor/Cargo.toml index 8e81d2c..86f2a1f 100644 --- a/crates/contractor/Cargo.toml +++ b/crates/contractor/Cargo.toml @@ -12,7 +12,7 @@ clap.workspace = true dotenv.workspace = true axum.workspace = true -serde = { version = "1.0.199", features = ["derive"] } +serde = { version = "1.0.200", features = ["derive"] } sqlx = { version = "0.7.4", features = ["runtime-tokio", "tls-rustls", "postgres", "uuid", "time"] } uuid = { version = "1.8.0", features = ["v4"] } tower-http = { version = "0.5.2", features = ["cors", "trace"] } -- 2.45.2 From 590f168742ee33e7e0afdfd42fae97061d72fa79 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Wed, 8 May 2024 00:46:42 +0000 Subject: [PATCH 51/74] fix(deps): update all dependencies --- Cargo.lock | 12 ++++++------ crates/contractor/Cargo.toml | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 00810a6..9948981 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1928,18 +1928,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.200" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" +checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.200" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" +checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" dependencies = [ "proc-macro2", "quote", @@ -1948,9 +1948,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", diff --git a/crates/contractor/Cargo.toml b/crates/contractor/Cargo.toml index 86f2a1f..49c6ae1 100644 --- a/crates/contractor/Cargo.toml +++ b/crates/contractor/Cargo.toml @@ -12,7 +12,7 @@ clap.workspace = true dotenv.workspace = true axum.workspace = true -serde = { version = "1.0.200", features = ["derive"] } +serde = { version = "1.0.201", features = ["derive"] } sqlx = { version = "0.7.4", features = ["runtime-tokio", "tls-rustls", "postgres", "uuid", "time"] } uuid = { version = "1.8.0", features = ["v4"] } tower-http = { version = "0.5.2", features = ["cors", "trace"] } @@ -20,6 +20,6 @@ futures = "0.3.30" reqwest = {version = "0.12.4", default-features = false, features = ["json", "rustls-tls"]} itertools = "0.12.1" regex = "1.10.4" -serde_json = "1.0.116" +serde_json = "1.0.117" dagger-sdk = "0.9.8" backon = "0.4.4" -- 2.45.2 From f8f211114961ba8c6a3ae35525f34aa3a7b33138 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Wed, 15 May 2024 08:38:45 +0000 Subject: [PATCH 52/74] fix(deps): update rust crate serde to 1.0.202 --- Cargo.lock | 8 ++++---- crates/contractor/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9948981..4cef235 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1928,18 +1928,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.201" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.201" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", diff --git a/crates/contractor/Cargo.toml b/crates/contractor/Cargo.toml index 49c6ae1..84b497f 100644 --- a/crates/contractor/Cargo.toml +++ b/crates/contractor/Cargo.toml @@ -12,7 +12,7 @@ clap.workspace = true dotenv.workspace = true axum.workspace = true -serde = { version = "1.0.201", features = ["derive"] } +serde = { version = "1.0.202", features = ["derive"] } sqlx = { version = "0.7.4", features = ["runtime-tokio", "tls-rustls", "postgres", "uuid", "time"] } uuid = { version = "1.8.0", features = ["v4"] } tower-http = { version = "0.5.2", features = ["cors", "trace"] } -- 2.45.2 From 753ecff59f905fc198ca7e4d0980a6f89b683dac Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Thu, 16 May 2024 16:24:03 +0000 Subject: [PATCH 53/74] fix(deps): update rust crate itertools to 0.13.0 --- Cargo.lock | 13 +++++++++++-- crates/contractor/Cargo.toml | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4cef235..d9d62bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -361,7 +361,7 @@ dependencies = [ "dagger-sdk", "dotenv", "futures", - "itertools", + "itertools 0.13.0", "regex", "reqwest 0.12.4", "serde", @@ -1223,6 +1223,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -2085,7 +2094,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" dependencies = [ - "itertools", + "itertools 0.12.1", "nom", "unicode_categories", ] diff --git a/crates/contractor/Cargo.toml b/crates/contractor/Cargo.toml index 84b497f..f4ba504 100644 --- a/crates/contractor/Cargo.toml +++ b/crates/contractor/Cargo.toml @@ -18,7 +18,7 @@ uuid = { version = "1.8.0", features = ["v4"] } tower-http = { version = "0.5.2", features = ["cors", "trace"] } futures = "0.3.30" reqwest = {version = "0.12.4", default-features = false, features = ["json", "rustls-tls"]} -itertools = "0.12.1" +itertools = "0.13.0" regex = "1.10.4" serde_json = "1.0.117" dagger-sdk = "0.9.8" -- 2.45.2 From 8474592738ba3c01fd6dd6f83910c7efc38a3a00 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Sat, 25 May 2024 18:34:46 +0000 Subject: [PATCH 54/74] fix(deps): update rust crate serde to v1.0.203 --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d9d62bb..0bb8aad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1937,18 +1937,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", -- 2.45.2 From b633c6da1d3f4a92b24e551ef6263e7201502958 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Sat, 6 Jul 2024 13:28:39 +0000 Subject: [PATCH 55/74] chore(deps): update all dependencies --- Cargo.lock | 135 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 95 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0bb8aad..1714257 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,9 +95,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.82" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "ascii" @@ -287,9 +287,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.4" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d" dependencies = [ "clap_builder", "clap_derive", @@ -297,9 +297,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708" dependencies = [ "anstream", "anstyle", @@ -309,9 +309,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -363,7 +363,7 @@ dependencies = [ "futures", "itertools 0.13.0", "regex", - "reqwest 0.12.4", + "reqwest 0.12.5", "serde", "serde_json", "sqlx", @@ -1141,19 +1141,20 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.26.0" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" +checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" dependencies = [ "futures-util", "http 1.1.0", "hyper 1.2.0", "hyper-util", - "rustls 0.22.3", + "rustls 0.23.10", "rustls-pki-types", "tokio", - "tokio-rustls 0.25.0", + "tokio-rustls 0.26.0", "tower-service", + "webpki-roots 0.26.1", ] [[package]] @@ -1609,6 +1610,53 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quinn" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ceeeeabace7857413798eb1ffa1e9c905a9946a57d81fb69b4b71c4d8eb3ad" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls 0.23.10", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddf517c03a109db8100448a4be38d498df8a210a99fe0e1b9eaf39e78c640efe" +dependencies = [ + "bytes", + "rand", + "ring", + "rustc-hash", + "rustls 0.23.10", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9096629c45860fc7fb143e125eb826b5e721e10be3263160c7d60ca832cf8c46" +dependencies = [ + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "quote" version = "1.0.36" @@ -1670,9 +1718,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -1742,9 +1790,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" +checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" dependencies = [ "base64 0.22.0", "bytes", @@ -1754,7 +1802,7 @@ dependencies = [ "http-body 1.0.0", "http-body-util", "hyper 1.2.0", - "hyper-rustls 0.26.0", + "hyper-rustls 0.27.2", "hyper-util", "ipnet", "js-sys", @@ -1763,15 +1811,16 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.22.3", + "quinn", + "rustls 0.23.10", "rustls-pemfile 2.1.2", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 0.1.2", + "sync_wrapper 1.0.1", "tokio", - "tokio-rustls 0.25.0", + "tokio-rustls 0.26.0", "tower-service", "url", "wasm-bindgen", @@ -1822,6 +1871,12 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustix" version = "0.38.32" @@ -1849,14 +1904,14 @@ dependencies = [ [[package]] name = "rustls" -version = "0.22.3" +version = "0.23.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" +checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402" dependencies = [ - "log", + "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.102.2", + "rustls-webpki 0.102.5", "subtle", "zeroize", ] @@ -1882,9 +1937,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.4.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" @@ -1898,9 +1953,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.2" +version = "0.102.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +checksum = "f9a6fccd794a42c2c105b513a2f62bc3fd8f3ba57a4593677ceb0bd035164d78" dependencies = [ "ring", "rustls-pki-types", @@ -1957,9 +2012,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", @@ -2489,9 +2544,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ "backtrace", "bytes", @@ -2508,9 +2563,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", @@ -2529,11 +2584,11 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.22.3", + "rustls 0.23.10", "rustls-pki-types", "tokio", ] @@ -2752,9 +2807,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" dependencies = [ "getrandom", ] -- 2.45.2 From 1fcd7e3946cab35acc3947c3a58f83f547532aa8 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Wed, 21 Aug 2024 20:46:38 +0000 Subject: [PATCH 56/74] fix(deps): update rust crate serde to v1.0.208 --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1714257..70b437c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1992,18 +1992,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.203" +version = "1.0.208" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.208" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" dependencies = [ "proc-macro2", "quote", -- 2.45.2 From 6d2baea123960240d811b38d33fe2bd762d4fa97 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Sat, 24 Aug 2024 03:45:20 +0000 Subject: [PATCH 57/74] fix(deps): update rust crate serde to v1.0.209 --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 70b437c..b4812ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1992,18 +1992,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.208" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" +checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.208" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" +checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", -- 2.45.2 From dad14c9858272e405e56ff57f332967d91d3db18 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Fri, 30 Aug 2024 08:16:44 +0000 Subject: [PATCH 58/74] fix(deps): update all dependencies --- Cargo.lock | 44 +++++++++++++++++--------------------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b4812ab..5c0d3a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" @@ -287,9 +287,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.8" +version = "4.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d" +checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" dependencies = [ "clap_builder", "clap_derive", @@ -297,9 +297,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.8" +version = "4.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708" +checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" dependencies = [ "anstream", "anstyle", @@ -309,9 +309,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.8" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -1357,13 +1357,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.11" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1439,16 +1440,6 @@ dependencies = [ "libm", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "object" version = "0.32.2" @@ -2544,28 +2535,27 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.0" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", -- 2.45.2 From 42d5528bc62f84d5ce78d6e557ba55002a0291c0 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Sat, 7 Sep 2024 00:18:29 +0000 Subject: [PATCH 59/74] chore(deps): update all dependencies --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c0d3a8..56ee42e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,9 +95,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" [[package]] name = "ascii" @@ -287,9 +287,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.16" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", "clap_derive", @@ -297,9 +297,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstream", "anstyle", -- 2.45.2 From 4778edc532d0f9fe9a3f67f92ae0180abdec74ba Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Sat, 7 Sep 2024 04:17:20 +0000 Subject: [PATCH 60/74] fix(deps): update rust crate serde to v1.0.210 --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 56ee42e..5406450 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1983,18 +1983,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", -- 2.45.2 From d5626cb1ee645be3e3314e49b785dedb982b649a Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Thu, 12 Sep 2024 00:20:46 +0000 Subject: [PATCH 61/74] chore(deps): update all dependencies --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5406450..585c4d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,9 +95,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.87" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" +checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356" [[package]] name = "ascii" -- 2.45.2 From 36d27a9a356762bcc3e8be65cd76cb316eb97788 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Sun, 15 Sep 2024 04:18:51 +0000 Subject: [PATCH 62/74] chore(deps): update all dependencies --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 585c4d6..fe94e93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,9 +95,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.88" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "ascii" -- 2.45.2 From 225fc71b1020afc128bac871f7ef9167fd482180 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Sat, 21 Sep 2024 00:37:25 +0000 Subject: [PATCH 63/74] chore(deps): update all dependencies --- Cargo.lock | 50 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fe94e93..0f8dbde 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -133,9 +133,9 @@ checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "axum" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" +checksum = "8f43644eed690f5374f1af436ecd6aea01cd201f6fbdf0178adaf6907afb2cec" dependencies = [ "async-trait", "axum-core", @@ -159,7 +159,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper 1.0.1", "tokio", - "tower", + "tower 0.5.1", "tower-layer", "tower-service", "tracing", @@ -167,9 +167,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +checksum = "5e6b8ba012a258d63c9adfa28b9ddcf66149da6f986c5b5452e629d5ee64bf00" dependencies = [ "async-trait", "bytes", @@ -180,7 +180,7 @@ dependencies = [ "mime", "pin-project-lite", "rustversion", - "sync_wrapper 0.1.2", + "sync_wrapper 1.0.1", "tower-layer", "tower-service", "tracing", @@ -287,9 +287,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.17" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" +checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" dependencies = [ "clap_builder", "clap_derive", @@ -297,9 +297,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.17" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" +checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" dependencies = [ "anstream", "anstyle", @@ -309,9 +309,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -1172,7 +1172,7 @@ dependencies = [ "pin-project-lite", "socket2", "tokio", - "tower", + "tower 0.4.13", "tower-service", "tracing", ] @@ -2624,6 +2624,22 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 0.1.2", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower-http" version = "0.5.2" @@ -2643,15 +2659,15 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -- 2.45.2 From 8b5af48c813f3bd8563033e3e1cc8f9b592cd98b Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Sat, 28 Sep 2024 00:24:59 +0000 Subject: [PATCH 64/74] chore(deps): update all dependencies --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f8dbde..7167bcc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -133,9 +133,9 @@ checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "axum" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f43644eed690f5374f1af436ecd6aea01cd201f6fbdf0178adaf6907afb2cec" +checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" dependencies = [ "async-trait", "axum-core", @@ -167,9 +167,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6b8ba012a258d63c9adfa28b9ddcf66149da6f986c5b5452e629d5ee64bf00" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ "async-trait", "bytes", -- 2.45.2 From d7d166fab7f25c48d9b6f40ed55b9d24600ce3da Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Wed, 2 Oct 2024 00:21:31 +0000 Subject: [PATCH 65/74] fix(deps): update all dependencies --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7167bcc..5c7b7c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -287,9 +287,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.18" +version = "4.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" +checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" dependencies = [ "clap_builder", "clap_derive", @@ -297,9 +297,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.18" +version = "4.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" +checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" dependencies = [ "anstream", "anstyle", -- 2.45.2 From 2649fa2dbed3c9fbe90af39310ee8dc3b7da5ef2 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Sun, 6 Oct 2024 00:21:00 +0000 Subject: [PATCH 66/74] fix(deps): update rust crate futures to v0.3.31 --- Cargo.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c7b7c5..5ac7568 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -731,9 +731,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -746,9 +746,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -756,15 +756,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -784,15 +784,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -801,21 +801,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", -- 2.45.2 From 1107302b0123d8a5282ccff2088051e76a90052e Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Wed, 9 Oct 2024 00:20:47 +0000 Subject: [PATCH 67/74] fix(deps): update all dependencies --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ac7568..8f43162 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -287,9 +287,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -297,9 +297,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.19" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", -- 2.45.2 From dc2d4974aca0210fb5ef211f0a79f623bb999aea Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Sun, 20 Oct 2024 04:21:57 +0000 Subject: [PATCH 68/74] chore(deps): update all dependencies --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8f43162..6a9d13c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,9 +95,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95" [[package]] name = "ascii" -- 2.45.2 From bb7e82b58a658629ac4cf10c13e7a3e838963805 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Wed, 23 Oct 2024 00:24:28 +0000 Subject: [PATCH 69/74] chore(deps): update all dependencies --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6a9d13c..acafaff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,9 +95,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.90" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95" +checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" [[package]] name = "ascii" @@ -2535,9 +2535,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.40.0" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" dependencies = [ "backtrace", "bytes", -- 2.45.2 From 13f43e7531a456a6d13d161b0d0f438f09c8677a Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Wed, 23 Oct 2024 04:25:31 +0000 Subject: [PATCH 70/74] fix(deps): update rust crate serde to v1.0.213 --- Cargo.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index acafaff..a38fbbe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,7 +113,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.82", ] [[package]] @@ -316,7 +316,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.82", ] [[package]] @@ -796,7 +796,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.82", ] [[package]] @@ -1528,7 +1528,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.82", ] [[package]] @@ -1594,9 +1594,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -1983,22 +1983,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.210" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.82", ] [[package]] @@ -2392,9 +2392,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.58" +version = "2.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" dependencies = [ "proc-macro2", "quote", @@ -2474,7 +2474,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.82", ] [[package]] @@ -2559,7 +2559,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.82", ] [[package]] @@ -2689,7 +2689,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.82", ] [[package]] @@ -2886,7 +2886,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.82", "wasm-bindgen-shared", ] @@ -2920,7 +2920,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.82", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3181,7 +3181,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.82", ] [[package]] -- 2.45.2 From 658dd61635afc828223b9a1cfd12b674e930b0cd Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Tue, 29 Oct 2024 01:23:44 +0000 Subject: [PATCH 71/74] fix(deps): update rust crate serde to v1.0.214 --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a38fbbe..7ef2acc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1983,18 +1983,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.213" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.213" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", -- 2.45.2 From 4bdab8e931b1e17b8346903a43ac1f67a2a63885 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Sat, 2 Nov 2024 01:22:49 +0000 Subject: [PATCH 72/74] chore(deps): update all dependencies --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7ef2acc..b08b129 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,9 +95,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" +checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" [[package]] name = "ascii" -- 2.45.2 From 763cae7244cf0c3ede96f00a18747a8b5a9e782b Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Thu, 7 Nov 2024 01:20:44 +0000 Subject: [PATCH 73/74] chore(deps): update all dependencies --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b08b129..ca98ec9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,9 +95,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "ascii" -- 2.45.2 From 1e3daf11408648998520ea3f5f9e76a235624345 Mon Sep 17 00:00:00 2001 From: Kasper Juul Hermansen Date: Fri, 8 Nov 2024 01:20:41 +0000 Subject: [PATCH 74/74] fix(deps): update all dependencies --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca98ec9..476dccb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2535,9 +2535,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.41.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", -- 2.45.2