3 Commits

Author SHA1 Message Date
89da9997ba add github provider (WIP) 2022-10-06 22:03:10 +02:00
d6d98c2ce8 v0.2 (#14)
Co-authored-by: kjuulh <contact@kjuulh.io>
Reviewed-on: #14
2022-09-21 22:55:52 +02:00
1f46f6ac8d v0.1 (#8)
Co-authored-by: kjuulh <contact@kjuulh.io>
Reviewed-on: kjuulh/kraken#8
2022-09-18 16:49:34 +02:00
59 changed files with 1583 additions and 611 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
.cuddle/
.env

1
CONFIGURATION_SERVER.md Normal file
View File

@@ -0,0 +1 @@
# Configuration server

249
README.md Normal file
View File

@@ -0,0 +1,249 @@
<p align="center">
<image src="https://git.front.kjuulh.io/kjuulh/octopush/raw/branch/v0.2/assets/octopush.svg" width="300" height="300"/>
</p>
<h1 align="center">Octopush - Your cute action executor</h1>
## Purpose
The goal of this project is to easily do batch changes or queries on a host of
repositories. In large organisations using multi-repository strategies, it may
be painful to change even small things across many repositories, because there
are so many of them. Octopush aims to change that.
**DISCLAIMER:** It is still early days, and the api is subject to change.
## Features
- Uses an actions repository, where you store all your pending commands or
queries to be performed across your fleet of repositories. (See \_examples)
- Actions can both execute changes, open pull-requests or in some cases commit
directly to your preferred branch
- Actions natively use either shell, go or docker files to execute changes
(see \_examples/actions)
- Actions can also be analytical, so you can query your fleet for whatever you
would like
- Works both as a client, or as a server
- Supports SSH/https for fetching repos
- Supports GPG signing
- Supports dry-run mode for easy testing when developing your actions (enabled
by default on the cli)
## Roadmap
Refer to [roadmap.md](roadmap.md)
## Installation
Octopush comes in two modes. Client or Client -> Server. Octopush can stand alone as
a client, for smaller and less secure changes. However, for organisations, it
may be useful to use Octopush in server mode, which supports more features, and
has extra security built in.
### Client (CLI)
Download executable from [releases](https://github.com/kjuulh/octopush/releases)
#### Or Use docker image
```bash
docker run --rm kasperhermansen/octopushcli:latest version
```
#### Or Build from source
```bash
git clone https://github.com/kjuulh/octopush.git
cd octopush
go build cmd/octopush/octopush.go
./octopush version
```
#### Or Build with cuddle
```bash
git clone https://github.com/kjuulh/octopush.git
cd octopush
cuddle_cli x build_cli
```
### Server
We prefer to run the server directly as a docker image.
```bash
docker pull kasperhermansen/octopushserver:latest
docker run -p 9090:80 --rm kasperhermansen/octopushserver:latest
```
#### Or Build from source
```bash
git clone https://github.com/kjuulh/octopush.git
cd octopush
go build cmd/server/server.go
./server version
```
#### Or Build with cuddle
```bash
git clone https://github.com/kjuulh/octopush.git
cd octopush
cuddle_cli x build_server
```
## Usage
**DISCLAIMER:** It is still early days, and the api of the CLI is subject to
change, this provides the aim of the project, but as it is currently in flux,
there may not be as much handholding in the actual usage.
I will focus on the client here, as the server provides the same features,
though available through the cli, but instead as configuration options (see
[CONFIGURATION_SERVER.md](CONFIGURATION_SERVER.md))
Octopush ships with autocomplete built in (courtesy of spf13/cobra). To add:
- Bash: `echo 'source <(octopush completion bash)' >> ~/.bashrc`
- Zsh: `echo 'source <(octopush completion zsh)' >> ~/.zshrc`
### Creating a new action
Creating a new action
```bash
git init my-actions # should only be done once
cd my-actions
octopush tmpl init write-a-readme --command
cat write-a-readme/octopush.yml
# Output
# apiVersion: git.front.kjuulh.io/kjuulh/octopush/blob/main/schema/v1
# name: write-a-readme
# select:
# repositories: []
# actions:
# - type: shell
# entry: "main.sh"
```
Octopush also ships with yaml schema, which should help write the yaml
configuration.
#### Add upstream repositories (victims)
Now add a preferred repository
```
cat << EOF > write-a-readme/octopush.yml
apiVersion: git.front.kjuulh.io/kjuulh/octopush/blob/main/schema/v1
name: write-a-readme
select:
providers: # new
- gitea: https://git.front.kjuulh.io # new
organisation: "kjuulh" # new
actions:
- type: shell
entry: "main.sh"
EOF
```
This will take all your repositories under an organisation and run the script
on.
Another could be to use
```bash
cat << EOF > write-a-readme/octopush.yml
apiVersion: git.front.kjuulh.io/kjuulh/octopush/blob/main/schema/v1
name: write-a-readme
select:
repositories: #new
- git@git.front.kjuulh.io:kjuulh/octopush.git #new
- git@git.front.kjuulh.io:kjuulh/octopush-test.git #new
actions:
- type: shell
entry: "main.sh"
EOF
```
This will just apply to those repositories instead. Both can also be combined
for a shared effect.
### Execute action
To run the script use
```bash
octopush process --path "write-a-readme"
```
This will cause the octopush process to automatically apply the action on the repo
and open a pr.
### Query repositories
Octopush can also be used to query.
```bash
cat << EOF > write-a-readme/octopush.yml
apiVersion: git.front.kjuulh.io/kjuulh/octopush/blob/main/schema/v1
name: write-a-readme
select:
repositories:
- git@git.front.kjuulh.io:kjuulh/octopush.git
- git@git.front.kjuulh.io:kjuulh/octopush-test.git
queries:
- type: grep
query: "# README"
EOF
```
Using the same command as above, will return the lines on each repo with those
criteria. Everything is run in docker, even locally, so no need to install fancy
tools.
Do note: All actions will be run as dry-run unless `--apply` is added. This is
to help test locally, as well as not cause serious issues. The server
configuration is pretty much the same, except the command would look like so:
`octopush server process --path "write-a-readme" --apply`. Octopush will try to
infer as much as possible, but it may be needed to apply some extra flags to
specify upstream repositories and such. Octopush will also help you setup keys and
such on the first run, using `octopush setup` or `octopush server setup`.
## Contributing
It is still early days, and as such things are moving fast, I may not be able to
implement features, because I am focusing my energy on the API. That said PRs
are welcome, though they are at your own risk.
### Bugs & features requests
Please use [issues](https://github.com/kjuulh/octopush/issues)
### Development
We use [cuddle](https://git.front.kjuulh.io/kjuulh/cuddle) to improve ease of
use, it is however, not a requirement, and probably won't need to be used
outside core maintainers.
Simply:
```bash
go run cmd/octopush/octopush.go # CLI
go run cmd/server/server.go # Server
```
We follow the `gofmt` formatting, along with optionally but recommend `golines`
If using cuddle
```
cuddle_cli x run # Run both server and client, will do a quick test sweep on the cli
cuddle_cli x watch_run # Automatically refresh both
cuddle_cli x fmt # will format the current code
```

View File

@@ -0,0 +1,11 @@
module write_a_readme
go 1.19
require github.com/bitfield/script v0.20.2
require (
bitbucket.org/creachadair/shell v0.0.7 // indirect
github.com/itchyny/gojq v0.12.7 // indirect
github.com/itchyny/timefmt-go v0.1.3 // indirect
)

View File

@@ -0,0 +1,20 @@
bitbucket.org/creachadair/shell v0.0.7 h1:Z96pB6DkSb7F3Y3BBnJeOZH2gazyMTWlvecSD4vDqfk=
bitbucket.org/creachadair/shell v0.0.7/go.mod h1:oqtXSSvSYr4624lnnabXHaBsYW6RD80caLi2b3hJk0U=
github.com/bitfield/script v0.20.2 h1:4DexsRtBILVMEn3EZwHbtJdDqdk43sXI8gM3F04JXgs=
github.com/bitfield/script v0.20.2/go.mod h1:l3AZPVAtKQrL03bwh7nlNTUtgrgSWurpJSbtqspYrOA=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/itchyny/gojq v0.12.7 h1:hYPTpeWfrJ1OT+2j6cvBScbhl0TkdwGM4bc66onUSOQ=
github.com/itchyny/gojq v0.12.7/go.mod h1:ZdvNHVlzPgUf8pgjnuDTmGfHA/21KoutQUJ3An/xNuw=
github.com/itchyny/timefmt-go v0.1.3 h1:7M3LGVDsqcd0VZH2U+x393obrzZisp7C0uEe921iRkU=
github.com/itchyny/timefmt-go v0.1.3/go.mod h1:0osSSCQSASBJMsIZnhAaF1C2fCBTJZXrnj37mG8/c+A=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -0,0 +1,25 @@
package main
import "github.com/bitfield/script"
func main() {
releaseRc := `
branches:
- "main"
- "v0.x"
plugins:
- "@semantic-release/commit-analyzer"
- "@semantic-release/release-notes-generator"
- "@semantic-release/changelog"
- "@semantic-release/git"
`
_, err := script.
Echo(releaseRc).
WriteFile(".releaserc.yml")
if err != nil {
panic(err)
}
}

View File

@@ -0,0 +1,12 @@
apiVersion: git.front.kjuulh.io/kjuulh/octopush/blob/main/schema/v1
name: write-a-readme
select:
repositories:
- git@git.front.kjuulh.io:kjuulh/octopush-test.git
#- git@git.front.kjuulh.io:kjuulh/octopush.git
# providers:
# - gitea: https://git.front.kjuulh.io
# organisation: "cibus"
actions:
- type: go
entry: "main.go"

View File

@@ -0,0 +1,8 @@
FROM debian:bullseye-slim
# Octopush relies on this path being the specified path
WORKDIR /src/work/
COPY entry.sh /src/script.sh
CMD [ "/src/script.sh" ]

View File

@@ -0,0 +1,5 @@
#!/bin/bash
set -e
echo "# README docker" > README.md

View File

@@ -0,0 +1,11 @@
module write_a_readme
go 1.19
require github.com/bitfield/script v0.20.2
require (
bitbucket.org/creachadair/shell v0.0.7 // indirect
github.com/itchyny/gojq v0.12.7 // indirect
github.com/itchyny/timefmt-go v0.1.3 // indirect
)

View File

@@ -0,0 +1,20 @@
bitbucket.org/creachadair/shell v0.0.7 h1:Z96pB6DkSb7F3Y3BBnJeOZH2gazyMTWlvecSD4vDqfk=
bitbucket.org/creachadair/shell v0.0.7/go.mod h1:oqtXSSvSYr4624lnnabXHaBsYW6RD80caLi2b3hJk0U=
github.com/bitfield/script v0.20.2 h1:4DexsRtBILVMEn3EZwHbtJdDqdk43sXI8gM3F04JXgs=
github.com/bitfield/script v0.20.2/go.mod h1:l3AZPVAtKQrL03bwh7nlNTUtgrgSWurpJSbtqspYrOA=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/itchyny/gojq v0.12.7 h1:hYPTpeWfrJ1OT+2j6cvBScbhl0TkdwGM4bc66onUSOQ=
github.com/itchyny/gojq v0.12.7/go.mod h1:ZdvNHVlzPgUf8pgjnuDTmGfHA/21KoutQUJ3An/xNuw=
github.com/itchyny/timefmt-go v0.1.3 h1:7M3LGVDsqcd0VZH2U+x393obrzZisp7C0uEe921iRkU=
github.com/itchyny/timefmt-go v0.1.3/go.mod h1:0osSSCQSASBJMsIZnhAaF1C2fCBTJZXrnj37mG8/c+A=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -0,0 +1,11 @@
apiVersion: git.front.kjuulh.io/kjuulh/octopush/blob/main/schema/v1
name: write-a-readme
select:
repositories:
- git@git.front.kjuulh.io:kjuulh/octopush-test.git
# providers:
# - gitea: https://git.front.kjuulh.io
# organisation: "cibus"
actions:
- type: docker-build
entry: Dockerfile

View File

@@ -1,118 +0,0 @@
apiVersion: git.front.kjuulh.io/kjuulh/kraken/blob/main/schema/v1
name: write-a-readme
select:
repositories:
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
- git@git.front.kjuulh.io:kjuulh/kraken-test.git
providers:
- gitea: https://git.front.kjuulh.io
organisation: "cibus"
actions:
- type: go
entry: "main.go"

View File

@@ -0,0 +1,11 @@
apiVersion: git.front.kjuulh.io/kjuulh/octopush/blob/main/schema/v1
name: write-a-readme
select:
repositories:
- git@git.front.kjuulh.io:kjuulh/octopush-test.git
# providers:
# - gitea: https://git.front.kjuulh.io
# organisation: "cibus"
actions:
- type: go
entry: "main.go"

View File

@@ -0,0 +1,9 @@
apiVersion: git.front.kjuulh.io/kjuulh/octopush/blob/main/schema/v1
name: write-a-readme
select:
providers:
- gitea: https://git.front.kjuulh.io
organisation: "cibus"
queries:
- type: grep
query: "releaser"

View File

@@ -0,0 +1,11 @@
apiVersion: git.front.kjuulh.io/kjuulh/octopush/blob/main/schema/v1
name: write-a-readme
select:
repositories:
- git@git.front.kjuulh.io:kjuulh/octopush-test.git
# providers:
# - gitea: https://git.front.kjuulh.io
# organisation: "cibus"
queries:
- type: grep
query: "# README"

BIN
assets/octopush.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

10
assets/octopush.svg Normal file
View File

@@ -0,0 +1,10 @@
<svg width="1000" height="1000" viewBox="0 0 1000 1000" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M975 568C975 830.335 762.335 497 500 497C237.665 497 25 830.335 25 568C25 305.665 237.665 93 500 93C762.335 93 975 305.665 975 568Z" fill="#52DB78"/>
<path d="M237.436 856.185C165.693 827.571 320.875 755.464 377.754 612.854C434.634 470.243 371.672 311.132 443.414 339.746C515.157 368.36 527.205 507.165 470.326 649.776C413.446 792.386 309.178 884.799 237.436 856.185Z" fill="#52DB78"/>
<path d="M428.353 849.847C353.918 829.229 500.308 740.627 541.293 592.663C582.278 444.699 502.337 293.405 576.773 314.023C651.208 334.641 678.325 471.303 637.34 619.267C596.355 767.231 502.788 870.465 428.353 849.847Z" fill="#52DB78"/>
<path d="M598.707 855.902C523.231 839.498 664.415 742.813 697.024 592.781C729.634 442.748 641.321 296.183 716.797 312.588C792.272 328.992 827.022 463.916 794.413 613.948C761.803 763.98 674.183 872.307 598.707 855.902Z" fill="#52DB78"/>
<path d="M47.896 838.855C-19.3259 800.817 144.17 750.323 219.784 616.698C295.397 483.073 254.495 316.918 321.717 354.956C388.938 392.994 382.136 532.155 306.522 665.78C230.909 799.405 115.118 876.893 47.896 838.855Z" fill="#52DB78"/>
<ellipse cx="605.35" cy="265.255" rx="57.5" ry="36.5" transform="rotate(-40.9544 605.35 265.255)" fill="white"/>
<ellipse cx="359.35" cy="265.255" rx="57.5" ry="36.5" transform="rotate(-40.9544 359.35 265.255)" fill="white"/>
<path d="M385.635 374C385.635 374 391.199 435.298 463.528 438.425C535.857 441.553 538.492 380.61 538.492 380.61" stroke="white" stroke-width="8"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,53 +0,0 @@
package commands
import (
"bytes"
"encoding/json"
"net/http"
"github.com/spf13/cobra"
)
func CreateKrakenProcessCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "process",
Run: func(cmd *cobra.Command, _ []string) {
client := http.Client{}
var buf bytes.Buffer
err := json.NewEncoder(&buf).
Encode(struct {
Repository string `json:"repository"`
Branch string `json:"branch"`
Path string `json:"path"`
}{
Repository: "git@git.front.kjuulh.io:kjuulh/kraken.git",
Branch: "feature/gitea-integration",
Path: "_examples/actions/write_a_readme/",
})
if err != nil {
panic(err)
}
req, err := http.NewRequestWithContext(
cmd.Context(),
http.MethodPost,
"http://localhost:3000/commands/processRepos",
&buf,
)
if err != nil {
panic(err)
}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
if resp.StatusCode >= 300 {
panic(resp.Status)
}
},
}
return cmd
}

View File

@@ -1,14 +0,0 @@
package commands
import "github.com/spf13/cobra"
func CreateKrakenCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "kraken",
// Run: func(cmd *cobra.Command, args []string) { },
}
cmd.AddCommand(CreateKrakenProcessCmd())
return cmd
}

View File

@@ -1,18 +0,0 @@
package main
import (
"os"
"git.front.kjuulh.io/kjuulh/kraken/cmd/kraken/commands"
)
func main() {
Execute()
}
func Execute() {
err := commands.CreateKrakenCmd().Execute()
if err != nil {
os.Exit(1)
}
}

View File

@@ -0,0 +1,61 @@
package commands
import (
"context"
"time"
"git.front.kjuulh.io/kjuulh/octopush/internal/cli"
"git.front.kjuulh.io/kjuulh/octopush/internal/commands"
"github.com/spf13/cobra"
"go.uber.org/zap"
)
func CreateOctopushProcessCmd(logger *zap.Logger) *cobra.Command {
var (
actionsRepo string
branch string
path string
)
cmd := &cobra.Command{
Use: "process",
RunE: func(cmd *cobra.Command, args []string) error {
if err := cmd.ParseFlags(args); err != nil {
return err
}
ctx := cmd.Context()
deps, cleanupFunc, err := cli.Start(ctx, logger)
if err != nil {
return err
}
defer func() {
ctx, _ = context.WithTimeout(ctx, time.Second*5)
if err := cleanupFunc(ctx); err != nil {
panic(err)
}
}()
err = commands.
NewProcessRepos(logger, deps).
Process(ctx, actionsRepo, branch, path)
if err != nil {
return err
}
return nil
},
}
pf := cmd.PersistentFlags()
pf.StringVar(&actionsRepo, "actions-repo", "", "actions repo is the location of your actions, not where to apply the actions themselves, that should be self contained")
cmd.MarkPersistentFlagRequired("actions-repo")
pf.StringVar(&branch, "branch", "main", "which branch to look for actions in, will default to main")
pf.StringVar(&path, "path", "", "the location of the path inside the repository")
cmd.MarkPersistentFlagRequired("path")
return cmd
}

View File

@@ -0,0 +1,18 @@
package commands
import (
"git.front.kjuulh.io/kjuulh/octopush/cmd/octopush/commands/server"
"github.com/spf13/cobra"
"go.uber.org/zap"
)
func CreateOctopushCmd(logger *zap.Logger) *cobra.Command {
cmd := &cobra.Command{
Use: "octopush",
}
cmd.AddCommand(CreateOctopushProcessCmd(logger))
cmd.AddCommand(server.CreateOctopushServerCmd(logger))
return cmd
}

View File

@@ -0,0 +1,73 @@
package server
import (
"bytes"
"encoding/json"
"net/http"
"github.com/spf13/cobra"
)
func CreateOctopushProcessCmd() *cobra.Command {
var (
actionsRepo string
branch string
path string
)
cmd := &cobra.Command{
Use: "process",
RunE: func(cmd *cobra.Command, args []string) error {
if err := cmd.ParseFlags(args); err != nil {
return err
}
client := http.Client{}
var buf bytes.Buffer
err := json.NewEncoder(&buf).
Encode(struct {
Repository string `json:"repository"`
Branch string `json:"branch"`
Path string `json:"path"`
}{
Repository: actionsRepo,
Branch: branch,
Path: path,
})
if err != nil {
panic(err)
}
req, err := http.NewRequestWithContext(
cmd.Context(),
http.MethodPost,
"http://localhost:3000/commands/processRepos",
&buf,
)
if err != nil {
panic(err)
}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
if resp.StatusCode >= 300 {
panic(resp.Status)
}
return nil
},
}
pf := cmd.PersistentFlags()
pf.StringVar(&actionsRepo, "actions-repo", "", "actions repo is the location of your actions, not where to apply the actions themselves, that should be self contained")
cmd.MarkPersistentFlagRequired("actions-repo")
pf.StringVar(&branch, "branch", "main", "which branch to look for actions in, will default to main")
pf.StringVar(&path, "path", "", "the location of the path inside the repository")
cmd.MarkPersistentFlagRequired("path")
return cmd
}

View File

@@ -0,0 +1,16 @@
package server
import (
"github.com/spf13/cobra"
"go.uber.org/zap"
)
func CreateOctopushServerCmd(logger *zap.Logger) *cobra.Command {
cmd := &cobra.Command{
Use: "server",
}
cmd.AddCommand(CreateOctopushProcessCmd())
return cmd
}

28
cmd/octopush/octopush.go Normal file
View File

@@ -0,0 +1,28 @@
package main
import (
"os"
"git.front.kjuulh.io/kjuulh/octopush/cmd/octopush/commands"
"git.front.kjuulh.io/kjuulh/octopush/internal/logger"
"go.uber.org/zap"
)
func main() {
logger, err := logger.New()
if err != nil {
panic(err)
}
_ = logger.Sync()
zap.ReplaceGlobals(logger)
Execute(logger)
}
func Execute(logger *zap.Logger) {
err := commands.CreateOctopushCmd(logger).Execute()
if err != nil {
os.Exit(1)
}
}

View File

@@ -7,7 +7,7 @@ import (
func CreateServerCmd(logger *zap.Logger) *cobra.Command {
cmd := &cobra.Command{
Use: "krakenserver",
Use: "octopushserver",
}
cmd.AddCommand(NewStartServerCommand(logger))

View File

@@ -1,7 +1,7 @@
package commands
import (
"git.front.kjuulh.io/kjuulh/kraken/internal/server"
"git.front.kjuulh.io/kjuulh/octopush/internal/server"
"github.com/spf13/cobra"
"go.uber.org/zap"
)
@@ -9,7 +9,7 @@ import (
func NewStartServerCommand(logger *zap.Logger) *cobra.Command {
cmd := &cobra.Command{
Use: "start",
Short: "Start the kraken server",
Short: "Start the octopush server",
RunE: func(cmd *cobra.Command, args []string) error {
return server.Start(logger)
},

View File

@@ -3,8 +3,8 @@ package main
import (
"os"
"git.front.kjuulh.io/kjuulh/kraken/cmd/server/commands"
"git.front.kjuulh.io/kjuulh/kraken/internal/logger"
"git.front.kjuulh.io/kjuulh/octopush/cmd/server/commands"
"git.front.kjuulh.io/kjuulh/octopush/internal/logger"
"go.uber.org/zap"
)

View File

@@ -3,9 +3,15 @@
base: "git@git.front.kjuulh.io:kjuulh/cuddle-go-plan.git"
vars:
service: "kraken"
service: "octopush"
deployments: "git@git.front.kjuulh.io:kjuulh/deployments.git"
scripts:
push_github:
type: shell
run_server:
type: shell
run_client:
type: shell
run:
type: shell

16
go.mod
View File

@@ -1,25 +1,26 @@
module git.front.kjuulh.io/kjuulh/kraken
module git.front.kjuulh.io/kjuulh/octopush
go 1.19
require (
git.front.kjuulh.io/kjuulh/curre v1.2.2
code.gitea.io/sdk/gitea v0.15.1
git.front.kjuulh.io/kjuulh/curre v1.3.5
github.com/ProtonMail/go-crypto v0.0.0-20220822140716-1678d6eb0cbe
github.com/ProtonMail/gopenpgp/v2 v2.4.10
github.com/gin-contrib/zap v0.0.2
github.com/gin-gonic/gin v1.8.1
github.com/go-git/go-git/v5 v5.4.2
github.com/google/go-github v17.0.0+incompatible
github.com/google/uuid v1.3.0
github.com/spf13/cobra v1.5.0
github.com/stretchr/testify v1.8.0
github.com/whilp/git-urls v1.0.0
go.uber.org/zap v1.23.0
golang.org/x/net v0.0.0-20220909164309-bea034e7d591
gopkg.in/yaml.v3 v3.0.1
)
require (
code.gitea.io/sdk/gitea v0.15.1 // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f // indirect
github.com/acomagu/bufpipe v1.0.3 // indirect
github.com/cloudflare/circl v1.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
@@ -31,6 +32,8 @@ require (
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.10.0 // indirect
github.com/goccy/go-json v0.9.7 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/hashicorp/go-version v1.2.1 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
@@ -43,10 +46,8 @@ require (
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sergi/go-diff v1.2.0 // indirect
github.com/sirupsen/logrus v1.7.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/ugorji/go/codec v1.2.7 // indirect
github.com/xanzy/ssh-agent v0.3.2 // indirect
@@ -58,5 +59,4 @@ require (
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

34
go.sum
View File

@@ -1,9 +1,8 @@
code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE=
code.gitea.io/sdk/gitea v0.15.1 h1:WJreC7YYuxbn0UDaPuWIe/mtiNKTvLN8MLkaw71yx/M=
code.gitea.io/sdk/gitea v0.15.1/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA=
git.front.kjuulh.io/kjuulh/curre v1.2.2 h1:0OwWIfekrMykdQg9bdmG80I+Mjc2k4i+sy903phuDWs=
git.front.kjuulh.io/kjuulh/curre v1.2.2/go.mod h1:m7WpSehONLqPh/XF3F0BI0UOpLOfGuDmDEFI1XsM6fE=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
git.front.kjuulh.io/kjuulh/curre v1.3.5 h1:oKYh5Z0vInjViLnS4ppzK0G2Mnj7vXq8mA5i/rsWId4=
git.front.kjuulh.io/kjuulh/curre v1.3.5/go.mod h1:m7WpSehONLqPh/XF3F0BI0UOpLOfGuDmDEFI1XsM6fE=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
@@ -11,10 +10,6 @@ github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/ProtonMail/go-crypto v0.0.0-20220822140716-1678d6eb0cbe h1:R2HeCk7SG/XpoYZlEeI1v7sId7w2AMWwzOaVqXn45FE=
github.com/ProtonMail/go-crypto v0.0.0-20220822140716-1678d6eb0cbe/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f h1:CGq7OieOz3wyQJ1fO8S0eO9TCW1JyvLrf8fhzz1i8ko=
github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f/go.mod h1:NYt+V3/4rEeDuaev/zw1zCq8uqVEuPHzDPo3OZrlGJ4=
github.com/ProtonMail/gopenpgp/v2 v2.4.10 h1:EYgkxzwmQvsa6kxxkgP1AwzkFqKHscF2UINxaSn6rdI=
github.com/ProtonMail/gopenpgp/v2 v2.4.10/go.mod h1:CTRA7/toc/4DxDy5Du4hPDnIZnJvXSeQ8LsRTOUJoyc=
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
@@ -69,8 +64,14 @@ github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGF
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
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.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.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=
@@ -130,8 +131,6 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
@@ -153,6 +152,8 @@ github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
github.com/whilp/git-urls v1.0.0 h1:95f6UMWN5FKW71ECsXRUd3FVYiXdrE7aX4NZKcPmIjU=
github.com/whilp/git-urls v1.0.0/go.mod h1:J16SAmobsqc3Qcy98brfl5f5+e0clUvg1krgwk/qCfE=
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
github.com/xanzy/ssh-agent v0.3.2 h1:eKj4SX2Fe7mui28ZgnFW5fmTz1EIr7ugo5s6wDxdHBM=
github.com/xanzy/ssh-agent v0.3.2/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
@@ -171,7 +172,6 @@ go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY=
go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
@@ -181,15 +181,7 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -208,7 +200,6 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -239,15 +230,12 @@ golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/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.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=

View File

@@ -7,7 +7,7 @@ import (
"os"
"testing"
"git.front.kjuulh.io/kjuulh/kraken/internal/server"
"git.front.kjuulh.io/kjuulh/octopush/internal/server"
"go.uber.org/zap"
)

View File

@@ -9,7 +9,7 @@ import (
"path"
"testing"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/storage"
"git.front.kjuulh.io/kjuulh/octopush/internal/services/storage"
"github.com/stretchr/testify/require"
)

View File

@@ -4,14 +4,15 @@ import (
"context"
"errors"
"git.front.kjuulh.io/kjuulh/kraken/internal/actions/builders"
"git.front.kjuulh.io/kjuulh/kraken/internal/schema"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/storage"
"git.front.kjuulh.io/kjuulh/octopush/internal/actions/builders"
"git.front.kjuulh.io/kjuulh/octopush/internal/actions/querier"
"git.front.kjuulh.io/kjuulh/octopush/internal/schema"
"git.front.kjuulh.io/kjuulh/octopush/internal/services/storage"
"go.uber.org/zap"
)
type Action struct {
Schema *schema.KrakenSchema
Schema *schema.OctopushSchema
SchemaPath string
}
@@ -30,6 +31,18 @@ func (a *Action) Execute(ctx context.Context, area *storage.Area) error {
zap.L().Debug("Execution done")
case "docker-build":
zap.L().Debug("Building docker-build")
runCmd, err := builders.NewDockerBuild(zap.L()).Build(ctx, a.SchemaPath, action.Entry)
if err != nil {
return err
}
err = runCmd(ctx, area.Path)
if err != nil {
return err
}
return nil
default:
return errors.New("could not determine action type")
}
@@ -37,3 +50,28 @@ func (a *Action) Execute(ctx context.Context, area *storage.Area) error {
return nil
}
func (a *Action) Query(ctx context.Context, area *storage.Area) ([]string, bool, error) {
for _, query := range a.Schema.Queries {
switch query.Type {
case "grep":
exe, err := querier.NewRipGrep(zap.L()).Build(ctx, a.SchemaPath, query.Query)
if err != nil {
return nil, false, err
}
output, found, err := exe(ctx, area.Path)
if err != nil {
return nil, false, err
}
zap.L().Debug("Execution done")
return output, found, nil
default:
return nil, false, errors.New("could not determine query type")
}
}
return nil, false, nil
}

View File

@@ -7,9 +7,9 @@ import (
"path"
"time"
"git.front.kjuulh.io/kjuulh/kraken/internal/schema"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/providers"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/storage"
"git.front.kjuulh.io/kjuulh/octopush/internal/schema"
"git.front.kjuulh.io/kjuulh/octopush/internal/services/providers"
"git.front.kjuulh.io/kjuulh/octopush/internal/services/storage"
"go.uber.org/zap"
)
@@ -23,12 +23,12 @@ type (
ActionCreator struct {
logger *zap.Logger
storage *storage.Service
git *providers.Git
git *providers.GoGit
}
ActionCreatorDeps interface {
GetStorageService() *storage.Service
GetGitProvider() *providers.Git
GetGitProvider() *providers.GoGit
}
)
@@ -59,19 +59,19 @@ func (ac *ActionCreator) Prepare(ctx context.Context, ops *ActionCreatorOps) (*A
return nil, fmt.Errorf("path is invalid: %s", ops.Path)
}
contents, err := os.ReadFile(path.Join(executorUrl, "kraken.yml"))
contents, err := os.ReadFile(path.Join(executorUrl, "octopush.yml"))
if err != nil {
return nil, err
}
krakenSchema, err := schema.Unmarshal(string(contents))
octopushSchema, err := schema.Unmarshal(string(contents))
if err != nil {
return nil, err
}
ac.logger.Debug("Action creator done")
return &Action{
Schema: krakenSchema,
Schema: octopushSchema,
SchemaPath: executorUrl,
}, nil
}

View File

@@ -0,0 +1,95 @@
package builders
import (
"context"
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"os"
"os/exec"
"go.uber.org/zap"
"go.uber.org/zap/zapio"
)
type DockerBuild struct {
logger *zap.Logger
}
func NewDockerBuild(logger *zap.Logger) *DockerBuild {
return &DockerBuild{logger: logger}
}
type DockerRunCommand func(ctx context.Context, victimPath string) error
func (g *DockerBuild) Build(ctx context.Context, modulePath, entryPath string) (DockerRunCommand, error) {
g.logger.Debug("Building docker image", zap.String("actiondir", modulePath), zap.String("entry", entryPath))
if _, err := os.Stat(fmt.Sprintf("%s/%s", modulePath, entryPath)); os.IsNotExist(err) {
return nil, errors.New("could not find entry")
}
b := make([]byte, 20)
_, err := rand.Reader.Read(b)
if err != nil {
return nil, err
}
tag := hex.EncodeToString(b)
buildDockerCmd := fmt.Sprintf("(cd %s; docker build -f %s --tag octopush/%s .)", modulePath, entryPath, tag)
g.logger.Debug("Running command", zap.String("command", buildDockerCmd))
cmd := exec.CommandContext(
ctx,
"/bin/bash",
"-c",
buildDockerCmd,
)
debugwriter := &zapio.Writer{
Log: g.logger,
Level: zap.DebugLevel,
}
defer debugwriter.Close()
cmd.Stdout = debugwriter
cmd.Stderr = debugwriter
err = cmd.Start()
if err != nil {
return nil, err
}
err = cmd.Wait()
if err != nil {
return nil, err
}
g.logger.Debug("Docker image built!")
return func(ctx context.Context, victimPath string) error {
g.logger.Debug("Executing script", zap.String("victim", victimPath))
cmd := exec.CommandContext(
ctx,
"/bin/bash",
"-c",
fmt.Sprintf("docker run --rm -v %s/:/src/work/ octopush/%s", victimPath, tag),
)
runDockerWriter := &zapio.Writer{
Log: g.logger,
Level: zap.DebugLevel,
}
defer runDockerWriter.Close()
cmd.Stdout = runDockerWriter
cmd.Stderr = runDockerWriter
err = cmd.Start()
if err != nil {
return err
}
return cmd.Wait()
}, nil
}

View File

@@ -0,0 +1,106 @@
package querier
import (
"context"
"fmt"
"io"
"os/exec"
"strings"
"go.uber.org/zap"
"go.uber.org/zap/zapio"
)
type RipGrep struct {
logger *zap.Logger
}
func NewRipGrep(logger *zap.Logger) *RipGrep {
return &RipGrep{logger: logger}
}
type RipGrepCommand func(ctx context.Context, victimPath string) ([]string, bool, error)
func (g *RipGrep) Build(ctx context.Context, modulePath, query string) (RipGrepCommand, error) {
g.logger.Debug("Pulling docker image", zap.String("actiondir", modulePath), zap.String("query", query))
pullDockerImage := "docker pull mbologna/docker-ripgrep"
g.logger.Debug("Running command", zap.String("command", pullDockerImage))
cmd := exec.CommandContext(
ctx,
"/bin/bash",
"-c",
pullDockerImage,
)
debugwriter := &zapio.Writer{
Log: g.logger,
Level: zap.DebugLevel,
}
defer debugwriter.Close()
cmd.Stdout = debugwriter
cmd.Stderr = debugwriter
err := cmd.Start()
if err != nil {
return nil, err
}
err = cmd.Wait()
if err != nil {
return nil, err
}
g.logger.Debug("Docker image pulled")
return func(ctx context.Context, victimPath string) ([]string, bool, error) {
g.logger.Debug("Executing script", zap.String("victim", victimPath))
runRipGrepCmd := fmt.Sprintf("docker run --rm -v %s/:/data:ro mbologna/docker-ripgrep rg -i '%s' || true", victimPath, query)
g.logger.Debug("Execute ripgrep query", zap.String("command", runRipGrepCmd))
cmd := exec.CommandContext(
ctx,
"/bin/bash",
"-c",
runRipGrepCmd,
)
runDockerWriter := &zapio.Writer{
Log: g.logger,
Level: zap.DebugLevel,
}
defer runDockerWriter.Close()
builder := &strings.Builder{}
combinedWriter := io.MultiWriter(runDockerWriter, builder)
cmd.Stdout = combinedWriter
cmd.Stderr = combinedWriter
err = cmd.Start()
if err != nil {
return nil, false, err
}
err = cmd.Wait()
if err != nil {
return nil, false, err
}
contents := strings.Split(builder.String(), "\n")
validatedOutput := make([]string, 0)
for _, c := range contents {
if !strings.Contains(c, "WARNING:") {
validatedOutput = append(validatedOutput, c)
}
}
found := len(validatedOutput) > 0
return validatedOutput, found, nil
}, nil
}

View File

@@ -4,9 +4,9 @@ import (
"context"
"net/http"
"git.front.kjuulh.io/kjuulh/kraken/internal/commands"
"git.front.kjuulh.io/kjuulh/kraken/internal/serverdeps"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/jobs"
"git.front.kjuulh.io/kjuulh/octopush/internal/commands"
"git.front.kjuulh.io/kjuulh/octopush/internal/serverdeps"
"git.front.kjuulh.io/kjuulh/octopush/internal/services/jobs"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"go.uber.org/zap"

View File

@@ -1,7 +1,7 @@
package api
import (
"git.front.kjuulh.io/kjuulh/kraken/internal/serverdeps"
"git.front.kjuulh.io/kjuulh/octopush/internal/serverdeps"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)

30
internal/cli/cli.go Normal file
View File

@@ -0,0 +1,30 @@
package cli
import (
"context"
"git.front.kjuulh.io/kjuulh/curre"
"git.front.kjuulh.io/kjuulh/octopush/internal/server"
"git.front.kjuulh.io/kjuulh/octopush/internal/serverdeps"
"git.front.kjuulh.io/kjuulh/octopush/internal/services/signer"
"go.uber.org/zap"
)
func Start(ctx context.Context, logger *zap.Logger) (*serverdeps.ServerDeps, curre.CleanupFunc, error) {
deps := serverdeps.NewServerDeps(logger)
readyChan := make(chan curre.ComponentsAreReady, 1)
cleanupFunc, err := curre.NewManager().
Register(
server.NewStorageServer(logger.With(zap.Namespace("storage")), deps),
).
Register(
signer.NewOpenPGPApp(deps.GetOpenPGP()),
).
RunNonBlocking(ctx, readyChan)
<-readyChan
return deps, cleanupFunc, err
}

View File

@@ -3,14 +3,16 @@ package commands
import (
"context"
"fmt"
"strings"
"sync"
"time"
"git.front.kjuulh.io/kjuulh/kraken/internal/actions"
"git.front.kjuulh.io/kjuulh/kraken/internal/gitproviders"
"git.front.kjuulh.io/kjuulh/kraken/internal/schema"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/providers"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/storage"
"git.front.kjuulh.io/kjuulh/octopush/internal/actions"
"git.front.kjuulh.io/kjuulh/octopush/internal/gitproviders"
"git.front.kjuulh.io/kjuulh/octopush/internal/schema"
"git.front.kjuulh.io/kjuulh/octopush/internal/services/providers"
"git.front.kjuulh.io/kjuulh/octopush/internal/services/storage"
giturls "github.com/whilp/git-urls"
"go.uber.org/zap"
)
@@ -18,14 +20,14 @@ type (
ProcessRepos struct {
logger *zap.Logger
storage *storage.Service
git *providers.Git
git *providers.GoGit
actionCreator *actions.ActionCreator
gitea *gitproviders.Gitea
}
ProcessReposDeps interface {
GetStorageService() *storage.Service
GetGitProvider() *providers.Git
GetGitProvider() *providers.GoGit
GetActionCreator() *actions.ActionCreator
GetGitea() *gitproviders.Gitea
}
@@ -42,8 +44,6 @@ func NewProcessRepos(logger *zap.Logger, deps ProcessReposDeps) *ProcessRepos {
}
func (pr *ProcessRepos) Process(ctx context.Context, repository string, branch string, actionPath string) error {
errChan := make(chan error, 1)
action, err := pr.actionCreator.Prepare(ctx, &actions.ActionCreatorOps{
RepositoryUrl: repository,
Branch: branch,
@@ -68,23 +68,18 @@ func (pr *ProcessRepos) Process(ctx context.Context, repository string, branch s
}()
err := pr.processRepo(ctx, repoUrl, action)
if err != nil {
errChan <- err
pr.logger.Error("could not process repo", zap.Error(err))
}
}(ctx, repoUrl)
}
wg.Wait()
close(errChan)
pr.logger.Debug("finished processing all repos", zap.Strings("repos", repositoryUrls))
for err := range errChan {
return err
}
return nil
}
func (pr *ProcessRepos) getRepoUrls(ctx context.Context, schema *schema.KrakenSchema) ([]string, error) {
func (pr *ProcessRepos) getRepoUrls(ctx context.Context, schema *schema.OctopushSchema) ([]string, error) {
repoUrls := make([]string, 0)
repoUrls = append(repoUrls, schema.Select.Repositories...)
@@ -117,17 +112,32 @@ func (pr *ProcessRepos) processRepo(ctx context.Context, repoUrl string, action
return err
}
err = action.Execute(ctx, area)
if err != nil {
return err
if len(action.Schema.Queries) > 0 {
result, found, err := action.Query(ctx, area)
if err != nil {
return err
}
if found {
pr.logger.Info("Query result", zap.Strings("result", result))
// TODO: Append to real result, and return together
}
}
err = pr.commit(ctx, area, repo)
if err != nil {
return err
if len(action.Schema.Actions) > 0 {
err = action.Execute(ctx, area)
if err != nil {
return err
}
err = pr.commit(ctx, area, repo, repoUrl)
if err != nil {
return err
}
}
pr.logger.Debug("processing done", zap.String("path", area.Path), zap.String("repoUrl", repoUrl))
return nil
}
@@ -151,7 +161,7 @@ func (pr *ProcessRepos) prepareAction(
return cleanupfunc, area, nil
}
func (pr *ProcessRepos) clone(ctx context.Context, area *storage.Area, repoUrl string) (*providers.GitRepo, error) {
func (pr *ProcessRepos) clone(ctx context.Context, area *storage.Area, repoUrl string) (*providers.GoGitRepo, error) {
pr.logger.Debug("Cloning repo", zap.String("path", area.Path), zap.String("repoUrl", repoUrl))
cloneCtx, _ := context.WithTimeout(ctx, time.Second*5)
repo, err := pr.git.Clone(cloneCtx, area, repoUrl)
@@ -167,23 +177,65 @@ func (pr *ProcessRepos) clone(ctx context.Context, area *storage.Area, repoUrl s
return repo, nil
}
func (pr *ProcessRepos) commit(ctx context.Context, area *storage.Area, repo *providers.GitRepo) error {
_, err := pr.git.Add(ctx, area, repo)
func (pr *ProcessRepos) commit(ctx context.Context, area *storage.Area, repo *providers.GoGitRepo, repoUrl string) error {
wt, err := pr.git.Add(ctx, area, repo)
if err != nil {
return fmt.Errorf("could not add file: %w", err)
}
status, err := wt.Status()
if err != nil {
return err
}
if status.IsClean() {
// TODO: check for pr
pr.logger.Info("Returning early, as no modifications are detected")
//return nil
}
err = pr.git.Commit(ctx, repo)
if err != nil {
return fmt.Errorf("could not get diff: %w", err)
}
dryrun := true
dryrun := false
if !dryrun {
err = pr.git.Push(ctx, repo)
if err != nil {
return fmt.Errorf("could not push to repo: %w", err)
}
url, err := giturls.Parse(repoUrl)
if err != nil {
return err
}
head, err := repo.GetHEAD()
if err != nil {
return err
}
path := strings.Split(url.Path, "/")
pr.logger.Debug("path string", zap.Strings("paths", path), zap.String("HEAD", head))
org := path[0]
repoName := path[1]
semanticName, _, ok := strings.Cut(repoName, ".")
if !ok {
semanticName = repoName
}
originHead, err := pr.git.GetOriginHEADForRepo(ctx, repo)
if err != nil {
return err
}
err = pr.gitea.CreatePr(ctx, fmt.Sprintf("%s://%s", "https", url.Host), org, semanticName, head, originHead, "octopush-apply")
if err != nil {
return err
}
}
return nil
}

View File

@@ -2,7 +2,9 @@ package gitproviders
import (
"context"
"errors"
"fmt"
"os"
"sync"
"code.gitea.io/sdk/gitea"
@@ -23,7 +25,11 @@ func NewGitea(logger *zap.Logger) *Gitea {
}
}
func (g *Gitea) ListRepositoriesForOrganization(ctx context.Context, server string, organization string) ([]string, error) {
func (g *Gitea) ListRepositoriesForOrganization(
ctx context.Context,
server string,
organization string,
) ([]string, error) {
client, err := g.getOrCreateClient(ctx, server)
if err != nil {
return nil, err
@@ -52,14 +58,82 @@ func (g *Gitea) ListRepositoriesForOrganization(ctx context.Context, server stri
return repoUrls, err
}
func (g *Gitea) CreatePr(
ctx context.Context,
server string,
organization string,
repository string,
head string,
base string,
actionName string,
) error {
client, err := g.getOrCreateClient(ctx, server)
if err != nil {
return err
}
prs, _, err := client.ListRepoPullRequests(organization, repository, gitea.ListPullRequestsOptions{
ListOptions: gitea.ListOptions{
Page: 0,
PageSize: 30,
},
State: gitea.StateOpen,
Sort: "recentupdate",
Milestone: 0,
})
if err != nil {
return fmt.Errorf(
"could not list repos, needed because we need to check for conflicts. Original error: %w",
err,
)
}
for _, pr := range prs {
if pr.Head.Name == head {
g.logger.Info(
"returning early from creating pull-request, as it already exists.",
zap.String("repository", repository),
zap.String("pull-request", pr.URL),
)
return nil
}
}
pr, _, err := client.CreatePullRequest(organization, repository, gitea.CreatePullRequestOption{
Head: head,
Base: base,
Title: actionName,
})
if err != nil {
return err
}
g.logger.Debug(
"Created pr",
zap.String("repository", repository),
zap.String("branch", head),
zap.String("pull-request", pr.URL),
)
return nil
}
func (g *Gitea) getOrCreateClient(ctx context.Context, server string) (*gitea.Client, error) {
g.giteamu.Lock()
defer g.giteamu.Unlock()
client, ok := g.giteaClients[server]
if !ok || client == nil {
c, err := gitea.NewClient(server)
username, ok := os.LookupEnv("GITEA_USERNAME")
if !ok {
return nil, errors.New("missing environment variable GITEA_USERNAME")
}
apitoken, ok := os.LookupEnv("GITEA_API_TOKEN")
if !ok {
return nil, errors.New("missing environment variable GITEA_API_TOKEN")
}
c.SetBasicAuth(username, apitoken)
if err != nil {
return nil, nil
return nil, err
}
g.giteaClients[server] = c
return c, nil

View File

@@ -0,0 +1,64 @@
package gitproviders
import (
"context"
"net/http"
"sync"
"github.com/google/go-github/github"
"go.uber.org/zap"
)
type Github struct {
logger *zap.Logger
githubmu sync.Mutex
githubClient map[string]*github.Client
}
func NewGitHub(logger *zap.Logger) *Github {
return &Github{
logger: logger,
githubmu: sync.Mutex{},
}
}
func (g *Github) ListRepositoriesForOrganization(
ctx context.Context,
server string,
organisation string,
) ([]string, error) {
client, err := g.getOrCreateClient(ctx, server)
repos, _, err := client.Repositories.ListByOrg(ctx, organisation, &github.RepositoryListByOrgOptions{
ListOptions: github.ListOptions{
Page: 0,
PerPage: 0,
},
})
if err != nil {
return nil, err
}
repoUrls := make([]string, len(repos))
for i, repo := range repos {
repoUrls[i] = repo.GetCloneURL()
}
return repoUrls, nil
}
func (g *Github) getOrCreateClient(ctx context.Context, server string) (*github.Client, error) {
g.githubmu.Lock()
defer g.githubmu.Unlock()
client, ok := g.githubClient[server]
if !ok || client == nil {
httpClient := &http.Client{}
client := github.NewClient(httpClient)
g.githubClient[server] = client
return client, nil
}
return client, nil
}

View File

@@ -12,7 +12,7 @@ func New() (*zap.Logger, error) {
return lvl >= zapcore.ErrorLevel
})
lowPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl < zapcore.ErrorLevel
return lvl < zapcore.ErrorLevel // && lvl > zapcore.DebugLevel
})
config := zap.NewDevelopmentEncoderConfig()
@@ -28,5 +28,6 @@ func New() (*zap.Logger, error) {
)
logger := zap.New(core)
return logger, nil
}

View File

@@ -2,7 +2,7 @@ package schema
import "gopkg.in/yaml.v3"
type KrakenSchema struct {
type OctopushSchema struct {
ApiVersion string `yaml:"apiVersion"`
Name string `yaml:"name"`
Select struct {
@@ -16,10 +16,14 @@ type KrakenSchema struct {
Type string `yaml:"type"`
Entry string `yaml:"entry"`
} `yaml:"actions"`
Queries []struct {
Type string `yaml:"type"`
Query string `yaml:"query"`
} `yaml:"queries"`
}
func Unmarshal(raw string) (*KrakenSchema, error) {
k := &KrakenSchema{}
func Unmarshal(raw string) (*OctopushSchema, error) {
k := &OctopushSchema{}
err := yaml.Unmarshal([]byte(raw), k)
if err != nil {
return nil, err

View File

@@ -7,8 +7,8 @@ import (
"time"
"git.front.kjuulh.io/kjuulh/curre"
"git.front.kjuulh.io/kjuulh/kraken/internal/api"
"git.front.kjuulh.io/kjuulh/kraken/internal/serverdeps"
"git.front.kjuulh.io/kjuulh/octopush/internal/api"
"git.front.kjuulh.io/kjuulh/octopush/internal/serverdeps"
ginzap "github.com/gin-contrib/zap"
"github.com/gin-gonic/gin"
"go.uber.org/zap"

View File

@@ -4,8 +4,8 @@ import (
"context"
"git.front.kjuulh.io/kjuulh/curre"
"git.front.kjuulh.io/kjuulh/kraken/internal/serverdeps"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/signer"
"git.front.kjuulh.io/kjuulh/octopush/internal/serverdeps"
"git.front.kjuulh.io/kjuulh/octopush/internal/services/signer"
"go.uber.org/zap"
)

View File

@@ -5,7 +5,7 @@ import (
"time"
"git.front.kjuulh.io/kjuulh/curre"
"git.front.kjuulh.io/kjuulh/kraken/internal/serverdeps"
"git.front.kjuulh.io/kjuulh/octopush/internal/serverdeps"
"go.uber.org/zap"
)

View File

@@ -1,12 +1,12 @@
package serverdeps
import (
actionc "git.front.kjuulh.io/kjuulh/kraken/internal/actions"
"git.front.kjuulh.io/kjuulh/kraken/internal/gitproviders"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/actions"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/providers"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/signer"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/storage"
actionc "git.front.kjuulh.io/kjuulh/octopush/internal/actions"
"git.front.kjuulh.io/kjuulh/octopush/internal/gitproviders"
"git.front.kjuulh.io/kjuulh/octopush/internal/services/actions"
"git.front.kjuulh.io/kjuulh/octopush/internal/services/providers"
"git.front.kjuulh.io/kjuulh/octopush/internal/services/signer"
"git.front.kjuulh.io/kjuulh/octopush/internal/services/storage"
"go.uber.org/zap"
)
@@ -53,7 +53,7 @@ func (deps *ServerDeps) GetStorageService() *storage.Service {
return storage.NewService(deps.logger.With(zap.Namespace("storage")), deps.storageConfig)
}
func (deps *ServerDeps) GetGitProvider() *providers.Git {
func (deps *ServerDeps) GetGitProvider() *providers.GoGit {
return providers.NewGit(deps.logger.With(zap.Namespace("gitProvider")), deps.gitCfg, deps.openPGP)
}

View File

@@ -3,7 +3,7 @@ package actions
import (
"context"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/storage"
"git.front.kjuulh.io/kjuulh/octopush/internal/services/storage"
"go.uber.org/zap"
)

View File

@@ -1,297 +1 @@
package providers
import (
"context"
"fmt"
"time"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/signer"
"git.front.kjuulh.io/kjuulh/kraken/internal/services/storage"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/plumbing/transport"
"github.com/go-git/go-git/v5/plumbing/transport/http"
"github.com/go-git/go-git/v5/plumbing/transport/ssh"
"go.uber.org/zap"
"go.uber.org/zap/zapio"
)
// Git is a native git provider, it can clone, pull
// , push and as in abstraction on native git operations
type Git struct {
logger *zap.Logger
gitConfig *GitConfig
openPGP *signer.OpenPGP
}
type GitRepo struct {
repo *git.Repository
}
type GitAuth string
const (
GIT_AUTH_SSH GitAuth = "ssh"
GIT_AUTH_USERNAME_PASSWORD GitAuth = "username_password"
GIT_AUTH_ACCESS_TOKEN GitAuth = "access_token"
GIT_AUTH_ANONYMOUS GitAuth = "anonymous"
GIT_AUTH_SSH_AGENT GitAuth = "ssh_agent"
)
type GitConfig struct {
AuthOption GitAuth
User string
Password string
AccessToken string
SshPublicKeyFilePath string
SshPrivateKeyPassword string
}
func NewGit(logger *zap.Logger, gitConfig *GitConfig, openPGP *signer.OpenPGP) *Git {
return &Git{logger: logger, gitConfig: gitConfig, openPGP: openPGP}
}
func (g *Git) CloneBranch(ctx context.Context, storageArea *storage.Area, repoUrl string, branch string) (*GitRepo, error) {
g.logger.Debug(
"cloning repository",
zap.String("repoUrl", repoUrl),
zap.String("path", storageArea.Path),
)
auth, err := g.GetAuth()
if err != nil {
return nil, err
}
cloneOptions := git.CloneOptions{
URL: repoUrl,
Auth: auth,
RemoteName: "origin",
ReferenceName: plumbing.NewBranchReferenceName(branch),
SingleBranch: true,
NoCheckout: false,
Depth: 1,
RecurseSubmodules: 1,
Progress: g.getProgressWriter(),
Tags: 0,
InsecureSkipTLS: false,
CABundle: []byte{},
}
repo, err := git.PlainCloneContext(ctx, storageArea.Path, false, &cloneOptions)
if err != nil {
return nil, err
}
g.logger.Debug("done cloning repo")
return &GitRepo{repo: repo}, nil
}
func (g *Git) Clone(ctx context.Context, storageArea *storage.Area, repoUrl string) (*GitRepo, error) {
g.logger.Debug(
"cloning repository",
zap.String("repoUrl", repoUrl),
zap.String("path", storageArea.Path),
)
auth, err := g.GetAuth()
if err != nil {
return nil, err
}
cloneOptions := git.CloneOptions{
URL: repoUrl,
Auth: auth,
RemoteName: "origin",
ReferenceName: "refs/heads/main",
SingleBranch: true,
NoCheckout: false,
Depth: 1,
RecurseSubmodules: 1,
Progress: g.getProgressWriter(),
Tags: 0,
InsecureSkipTLS: false,
CABundle: []byte{},
}
repo, err := git.PlainCloneContext(ctx, storageArea.Path, false, &cloneOptions)
if err != nil {
return nil, err
}
g.logger.Debug("done cloning repo")
return &GitRepo{repo: repo}, nil
}
func (g *Git) getProgressWriter() *zapio.Writer {
return &zapio.Writer{
Log: g.logger.With(zap.String("process", "go-git")),
Level: zap.DebugLevel,
}
}
func (g *Git) Add(ctx context.Context, storageArea *storage.Area, gitRepo *GitRepo) (*git.Worktree, error) {
worktree, err := gitRepo.repo.Worktree()
if err != nil {
return nil, err
}
err = worktree.AddWithOptions(&git.AddOptions{
All: true,
})
if err != nil {
return nil, err
}
status, err := worktree.Status()
if err != nil {
return nil, err
}
g.logger.Debug("git status", zap.String("status", status.String()))
return worktree, nil
}
func (g *Git) CreateBranch(ctx context.Context, gitRepo *GitRepo) error {
worktree, err := gitRepo.repo.Worktree()
if err != nil {
return err
}
refSpec := plumbing.NewBranchReferenceName("kraken-apply")
err = gitRepo.repo.CreateBranch(&config.Branch{
Name: "kraken-apply",
Remote: "origin",
Merge: refSpec,
Rebase: "",
})
if err != nil {
return fmt.Errorf("could not create branch: %w", err)
}
err = worktree.Checkout(&git.CheckoutOptions{
Branch: plumbing.ReferenceName(refSpec.String()),
Create: true,
Force: false,
Keep: false,
})
if err != nil {
return fmt.Errorf("could not checkout branch: %w", err)
}
remoteRef := plumbing.NewRemoteReferenceName("origin", "kraken-apply")
ref := plumbing.NewSymbolicReference(refSpec, remoteRef)
err = gitRepo.repo.Storer.SetReference(ref)
if err != nil {
return fmt.Errorf("could not set reference: %w", err)
}
auth, err := g.GetAuth()
if err != nil {
return err
}
err = worktree.PullContext(ctx, &git.PullOptions{
RemoteName: "origin",
ReferenceName: "refs/heads/main",
SingleBranch: true,
Depth: 1,
Auth: auth,
RecurseSubmodules: 1,
Progress: g.getProgressWriter(),
Force: true,
InsecureSkipTLS: false,
CABundle: []byte{},
})
if err != nil {
return fmt.Errorf("could not pull from origin: %w", err)
}
g.logger.Debug("done creating branches")
return nil
}
func (g *Git) Commit(ctx context.Context, gitRepo *GitRepo) error {
worktree, err := gitRepo.repo.Worktree()
if err != nil {
return err
}
_, err = worktree.Commit("some-commit", &git.CommitOptions{
All: true,
Author: &object.Signature{Name: "kraken", Email: "kraken@kasperhermansen.com", When: time.Now()},
Committer: &object.Signature{Name: "kraken", Email: "kraken@kasperhermansen.com", When: time.Now()},
SignKey: g.openPGP.SigningKey,
})
if err != nil {
return err
}
g.logger.Debug("done commiting objects")
return nil
}
func (g *Git) Push(ctx context.Context, gitRepo *GitRepo) error {
auth, err := g.GetAuth()
if err != nil {
return err
}
err = gitRepo.repo.PushContext(ctx, &git.PushOptions{
RemoteName: "origin",
RefSpecs: []config.RefSpec{},
Auth: auth,
Progress: g.getProgressWriter(),
Prune: false,
Force: false,
InsecureSkipTLS: false,
CABundle: []byte{},
RequireRemoteRefs: []config.RefSpec{},
})
if err != nil {
return err
}
g.logger.Debug("done pushing branch")
return nil
}
func (g *Git) GetAuth() (transport.AuthMethod, error) {
switch g.gitConfig.AuthOption {
case GIT_AUTH_SSH:
sshKey, err := ssh.NewPublicKeysFromFile(
g.gitConfig.User,
g.gitConfig.SshPublicKeyFilePath,
g.gitConfig.SshPrivateKeyPassword,
)
if err != nil {
return nil, err
}
return sshKey, nil
case GIT_AUTH_USERNAME_PASSWORD:
return &http.BasicAuth{
Username: g.gitConfig.User,
Password: g.gitConfig.Password,
}, nil
case GIT_AUTH_ACCESS_TOKEN:
return &http.BasicAuth{
Username: "required-username",
Password: g.gitConfig.AccessToken,
}, nil
case GIT_AUTH_ANONYMOUS:
return nil, nil
case GIT_AUTH_SSH_AGENT:
return ssh.NewSSHAgentAuth(g.gitConfig.User)
default:
return nil, nil
}
}

View File

@@ -0,0 +1,339 @@
package providers
import (
"context"
"errors"
"fmt"
"time"
"git.front.kjuulh.io/kjuulh/octopush/internal/services/signer"
"git.front.kjuulh.io/kjuulh/octopush/internal/services/storage"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/plumbing/transport"
"github.com/go-git/go-git/v5/plumbing/transport/http"
"github.com/go-git/go-git/v5/plumbing/transport/ssh"
"go.uber.org/zap"
"go.uber.org/zap/zapio"
)
// GoGit is a native git provider, it can clone, pull
// , push and as in abstraction on native git operations
type GoGit struct {
logger *zap.Logger
gitConfig *GitConfig
openPGP *signer.OpenPGP
}
type GoGitRepo struct {
repo *git.Repository
}
func (gr *GoGitRepo) GetHEAD() (string, error) {
head, err := gr.repo.Head()
if err != nil {
return "", err
}
return head.Name().Short(), nil
}
type GitAuth string
const (
GIT_AUTH_SSH GitAuth = "ssh"
GIT_AUTH_USERNAME_PASSWORD GitAuth = "username_password"
GIT_AUTH_ACCESS_TOKEN GitAuth = "access_token"
GIT_AUTH_ANONYMOUS GitAuth = "anonymous"
GIT_AUTH_SSH_AGENT GitAuth = "ssh_agent"
)
type GitConfig struct {
AuthOption GitAuth
User string
Password string
AccessToken string
SshPublicKeyFilePath string
SshPrivateKeyPassword string
}
func NewGit(logger *zap.Logger, gitConfig *GitConfig, openPGP *signer.OpenPGP) *GoGit {
return &GoGit{logger: logger, gitConfig: gitConfig, openPGP: openPGP}
}
func (g *GoGit) GetOriginHEADForRepo(ctx context.Context, gitRepo *GoGitRepo) (string, error) {
auth, err := g.GetAuth()
if err != nil {
return "", err
}
remote, err := gitRepo.repo.Remote("origin")
if err != nil {
return "", err
}
refs, err := remote.ListContext(ctx, &git.ListOptions{
Auth: auth,
})
if err != nil {
return "", err
}
headRef := ""
for _, ref := range refs {
//g.logger.Debug(ref.String())
if ref.Target().IsBranch() {
headRef = ref.Target().Short()
}
}
if headRef == "" {
return "", errors.New("no upstream HEAD branch could be found")
}
return headRef, nil
}
func (g *GoGit) CloneBranch(ctx context.Context, storageArea *storage.Area, repoUrl string, branch string) (*GoGitRepo, error) {
g.logger.Debug(
"cloning repository",
zap.String("repoUrl", repoUrl),
zap.String("path", storageArea.Path),
)
auth, err := g.GetAuth()
if err != nil {
return nil, err
}
cloneOptions := git.CloneOptions{
URL: repoUrl,
Auth: auth,
RemoteName: "origin",
ReferenceName: plumbing.NewBranchReferenceName(branch),
SingleBranch: false,
NoCheckout: false,
Depth: 1,
RecurseSubmodules: 1,
Progress: g.getProgressWriter(),
Tags: 0,
InsecureSkipTLS: false,
CABundle: []byte{},
}
repo, err := git.PlainCloneContext(ctx, storageArea.Path, false, &cloneOptions)
if err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) {
return nil, err
}
g.logger.Debug("done cloning repo")
return &GoGitRepo{repo: repo}, nil
}
func (g *GoGit) Clone(ctx context.Context, storageArea *storage.Area, repoUrl string) (*GoGitRepo, error) {
g.logger.Debug(
"cloning repository",
zap.String("repoUrl", repoUrl),
zap.String("path", storageArea.Path),
)
auth, err := g.GetAuth()
if err != nil {
return nil, err
}
cloneOptions := git.CloneOptions{
URL: repoUrl,
Auth: auth,
RemoteName: "origin",
ReferenceName: "",
SingleBranch: false,
NoCheckout: false,
Depth: 1,
RecurseSubmodules: 1,
Progress: g.getProgressWriter(),
Tags: 0,
InsecureSkipTLS: false,
CABundle: []byte{},
}
repo, err := git.PlainCloneContext(ctx, storageArea.Path, false, &cloneOptions)
if err != nil {
return nil, err
}
g.logger.Debug("done cloning repo")
return &GoGitRepo{repo: repo}, nil
}
func (g *GoGit) getProgressWriter() *zapio.Writer {
return &zapio.Writer{
Log: g.logger.With(zap.String("process", "go-git")),
Level: zap.DebugLevel,
}
}
func (g *GoGit) Add(ctx context.Context, storageArea *storage.Area, gitRepo *GoGitRepo) (*git.Worktree, error) {
worktree, err := gitRepo.repo.Worktree()
if err != nil {
return nil, err
}
err = worktree.AddWithOptions(&git.AddOptions{
All: true,
})
if err != nil {
return nil, err
}
status, err := worktree.Status()
if err != nil {
return nil, err
}
g.logger.Debug("git status", zap.String("status", status.String()))
return worktree, nil
}
func (g *GoGit) CreateBranch(ctx context.Context, gitRepo *GoGitRepo) error {
worktree, err := gitRepo.repo.Worktree()
if err != nil {
return err
}
refSpec := plumbing.NewBranchReferenceName("octopush-apply")
err = gitRepo.repo.CreateBranch(&config.Branch{
Name: "octopush-apply",
Remote: "origin",
Merge: refSpec,
Rebase: "",
})
if err != nil {
return fmt.Errorf("could not create branch: %w", err)
}
err = worktree.Checkout(&git.CheckoutOptions{
Branch: plumbing.ReferenceName(refSpec.String()),
Create: true,
Force: false,
Keep: false,
})
if err != nil {
return fmt.Errorf("could not checkout branch: %w", err)
}
//remoteRef := plumbing.NewRemoteReferenceName("origin", "octopush-apply")
//ref := plumbing.NewSymbolicReference(refSpec, remoteRef)
//err = gitRepo.repo.Storer.SetReference(ref)
//if err != nil {
// return fmt.Errorf("could not set reference: %w", err)
//}
auth, err := g.GetAuth()
if err != nil {
return err
}
err = worktree.PullContext(ctx, &git.PullOptions{
RemoteName: "origin",
ReferenceName: "",
SingleBranch: false,
Depth: 1,
Auth: auth,
RecurseSubmodules: 1,
Progress: g.getProgressWriter(),
Force: true,
InsecureSkipTLS: false,
CABundle: []byte{},
})
if err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) {
return fmt.Errorf("could not pull from origin: %w", err)
}
g.logger.Debug("done creating branches")
return nil
}
func (g *GoGit) Commit(ctx context.Context, gitRepo *GoGitRepo) error {
worktree, err := gitRepo.repo.Worktree()
if err != nil {
return err
}
_, err = worktree.Commit("some-commit", &git.CommitOptions{
All: true,
Author: &object.Signature{Name: "octopush", Email: "octopush@kasperhermansen.com", When: time.Now()},
Committer: &object.Signature{Name: "octopush", Email: "octopush@kasperhermansen.com", When: time.Now()},
SignKey: g.openPGP.SigningKey,
})
if err != nil {
return err
}
g.logger.Debug("done commiting objects")
return nil
}
func (g *GoGit) Push(ctx context.Context, gitRepo *GoGitRepo) error {
auth, err := g.GetAuth()
if err != nil {
return err
}
err = gitRepo.repo.PushContext(ctx, &git.PushOptions{
RemoteName: "origin",
RefSpecs: []config.RefSpec{},
Auth: auth,
Progress: g.getProgressWriter(),
Prune: false,
Force: true,
InsecureSkipTLS: false,
CABundle: []byte{},
RequireRemoteRefs: []config.RefSpec{},
})
if err != nil {
return err
}
g.logger.Debug("done pushing branch")
return nil
}
func (g *GoGit) GetAuth() (transport.AuthMethod, error) {
switch g.gitConfig.AuthOption {
case GIT_AUTH_SSH:
sshKey, err := ssh.NewPublicKeysFromFile(
g.gitConfig.User,
g.gitConfig.SshPublicKeyFilePath,
g.gitConfig.SshPrivateKeyPassword,
)
if err != nil {
return nil, err
}
return sshKey, nil
case GIT_AUTH_USERNAME_PASSWORD:
return &http.BasicAuth{
Username: g.gitConfig.User,
Password: g.gitConfig.Password,
}, nil
case GIT_AUTH_ACCESS_TOKEN:
return &http.BasicAuth{
Username: "required-username",
Password: g.gitConfig.AccessToken,
}, nil
case GIT_AUTH_ANONYMOUS:
return nil, nil
case GIT_AUTH_SSH_AGENT:
return ssh.NewSSHAgentAuth(g.gitConfig.User)
default:
return nil, nil
}
}

View File

@@ -22,7 +22,7 @@ func NewDefaultStorageConfig() (*StorageConfig, error) {
return nil, err
}
return &StorageConfig{
Path: path.Join(tempDir, "kraken"),
Path: path.Join(tempDir, "octopush"),
}, nil
}

View File

@@ -19,17 +19,45 @@
## Version 0.1
- [x] Setup a way to choose actions and predicates
- [x] Allow instantiation of actions, kraken template repo etc.
- [ ] Create pr for gitea provider
- [ ] Think about some sort of isolation
- [ ] Create CLI to trigger action
- [ ] Setup pool of runners
- [ ] Run authenticated on servers
- [ ] Create queuing system
- [x] Allow instantiation of actions, octopush template repo etc.
- [x] Implement docker action
- [x] Create pr for gitea provider
- [x] Providing query results
- [x] Create CLI to trigger action
## Version 1.0
## Version 0.2
- [ ] Write README
- [x] Write README
- [x] Fix git issues
- [x] Allow octopush to run directly on the cli
## Version 0.3
- [ ] Make select depend on query
- [ ] Make configurable ssh user
- [ ] Make configurable gpg keyset
- [ ] Make configurable git provider
- [ ] Add github
- [ ] Create templating function for easily creating new actions
- [ ] Add way to see progress of runners
- [ ] Implement global .octopush store for easy access to settings
- [ ] Move builders to start instead of every building on every action
- [ ] Setup releases on github
- [ ] Setup CI
- [ ] Setup static analysis
- [ ] Setup releases on gitea using drone
- [ ] Figure out a license (probably MIT)
## Version 0.4
- [ ] Create setup version for local actions
- [ ] Create setup version for server actions
- [ ] Create json schema
- [ ] Move roadmap to release / changelog
## Version 0.x
- Think about some sort of isolation
- Run authenticated on servers
- Create queuing system
- Setup pool of runners

View File

@@ -2,6 +2,6 @@
set -e
git remote add github git@github.com:kjuulh/kraken.git || true
git remote add github git@github.com:kjuulh/octopush.git || true
git push -f github main
git push -f github --all

15
scripts/run.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/bash
set -e
run_server="cuddle_cli x run_server"
$run_server &
sleep 1s
cuddle_cli x run_client
sleep 5s
kill %1

13
scripts/run_client.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/bash
set -e
current_branch=$(git branch --show-current)
export $(cat .env | xargs)
#go run cmd/octopush/octopush.go process --actions-repo "git@git.front.kjuulh.io:kjuulh/octopush.git" --branch "$current_branch" --path "_examples/actions/write_a_readme"
go run cmd/octopush/octopush.go process \
--actions-repo "git@git.front.kjuulh.io:kjuulh/octopush.git"\
--branch "$current_branch" \
--path "_examples/actions/add_releaserc"

7
scripts/run_server.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
set -e
export $(cat .env | xargs)
go run cmd/server/server.go start