Skip to content

Commit dd6744c

Browse files
committed
Initial commit
0 parents  commit dd6744c

File tree

9 files changed

+626
-0
lines changed

9 files changed

+626
-0
lines changed

.github/workflows/ci.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main, golang ]
6+
pull_request:
7+
branches: [ main, golang ]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Set up Go
16+
uses: actions/setup-go@v4
17+
with:
18+
go-version: '1.24.1'
19+
20+
- name: Cache Go modules
21+
uses: actions/cache@v3
22+
with:
23+
path: ~/go/pkg/mod
24+
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
25+
restore-keys: |
26+
${{ runner.os }}-go-
27+
28+
- name: Download dependencies
29+
run: go mod download
30+
31+
- name: Verify dependencies
32+
run: go mod verify
33+
34+
- name: Check formatting
35+
run: |
36+
if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then
37+
echo "The following files are not formatted correctly:"
38+
gofmt -s -l .
39+
exit 1
40+
fi
41+
42+
- name: Run go vet
43+
run: go vet ./...
44+
45+
- name: Run tests
46+
run: go test -v ./...
47+
48+
- name: Run tests with race detector
49+
run: go test -race -v ./...
50+
51+
- name: Build
52+
run: go build -v ./...
53+
54+
- name: Test build for different architectures
55+
run: |
56+
GOOS=linux GOARCH=amd64 go build -o gh-deploy-linux-amd64 .
57+
GOOS=linux GOARCH=arm64 go build -o gh-deploy-linux-arm64 .

.github/workflows/release.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Release
2+
3+
on:
4+
release:
5+
types: [created]
6+
7+
jobs:
8+
release:
9+
runs-on: ubuntu-latest
10+
permissions:
11+
contents: write
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Set up Go
16+
uses: actions/setup-go@v4
17+
with:
18+
go-version: '1.24.1'
19+
20+
- name: Cache Go modules
21+
uses: actions/cache@v3
22+
with:
23+
path: ~/go/pkg/mod
24+
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
25+
restore-keys: |
26+
${{ runner.os }}-go-
27+
28+
- name: Download dependencies
29+
run: go mod download
30+
31+
- name: Build binaries
32+
run: |
33+
GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -trimpath -o gh-deploy-linux-amd64 .
34+
GOOS=linux GOARCH=arm64 go build -ldflags="-w -s" -trimpath -o gh-deploy-linux-arm64 .
35+
- name: Upload release assets
36+
uses: softprops/action-gh-release@v1
37+
with:
38+
files: |
39+
gh-deploy-linux-amd64
40+
gh-deploy-linux-arm64
41+
env:
42+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Binaries for programs and plugins
2+
*.exe
3+
*.exe~
4+
*.dll
5+
*.so
6+
*.dylib
7+
8+
# Test binary, built with `go test -c`
9+
*.test
10+
11+
# Output of the go coverage tool, specifically when used with LiteIDE
12+
*.out
13+
14+
# Go workspace file
15+
go.work
16+
17+
# Build artifacts
18+
/gh-deploy
19+
20+
# Configuration files with secrets
21+
config.toml
22+
*.pem
23+
.env
24+
25+
# IDE files
26+
.vscode/
27+
.idea/
28+
*.swp
29+
*.swo
30+
*~
31+
32+
# OS generated files
33+
.DS_Store
34+
.DS_Store?
35+
._*
36+
.Spotlight-V100
37+
.Trashes
38+
ehthumbs.db
39+
Thumbs.db

LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright 2020-2025 Nikita Sychev, Nikolay Amiantov
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of
4+
this software and associated documentation files (the “Software”), to deal in
5+
the Software without restriction, including without limitation the rights to
6+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7+
of the Software, and to permit persons to whom the Software is furnished to do
8+
so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# gh-deploy
2+
3+
🚀 Tool to deploy code from GitHub repositories to your servers.
4+
5+
## Installation
6+
7+
The preferred option is to use our interactive installer: https://teamteam.dev/gh-deploy/. It will guide you through GitHub App registration and creates required configuration files.
8+
9+
To install manually, create a GitHub App in your personal account on an organization that owns repositories you want to deploy. Set the following options:
10+
- Webhook URL: provide URL that you’ll deploy this tool to
11+
- Webhook events: `push`
12+
- Permissions: `contents:read` (Repository → Contents → Read-only)
13+
14+
Acquire client ID webhook secret, private key (PEM file). Install the application on your own account.
15+
16+
Then follow with one of the installation options:
17+
18+
### Systems that have systemd enabled
19+
20+
Decide which user will be running the tool. The following instructions suppose this user will be named `user` and has default group named `usergroup`. Execute these commands:
21+
22+
```bash
23+
sudo install -Ddm 755 -o root -g usergroup /etc/gh-deploy
24+
```
25+
26+
Then create files `/etc/gh-deploy/key.pem` and `/etc/gh-deploy/webhook-secret` with PEM file and webhook secret respectively. Then:
27+
28+
```bash
29+
sudo chmod 640 /etc/gh-deploy/key.pem /etc/gh-deploy/webhook-secret
30+
sudo chown root:usergroup /etc/gh-deploy/key.pem /etc/gh-deploy/webhook-secret
31+
32+
# This will download the latest release to /usr/local/bin/gh-deploy, create default config, install and start systemd unit.
33+
curl https://teamteam.dev/gh-deploy/install.sh | sudo APP_ID=<your-github-app-id> USER=user bash -
34+
```
35+
36+
Then update `/etc/gh-deploy/config.toml` to your preference and make the webhook available at URL specified before.
37+
38+
### NixOS
39+
40+
Use `flake.nix` that provides `gh-deploy` service.
41+
42+
### Other systems
43+
44+
You can fetch latest release from [Releases](https://github.com/teamteamdev/gh-deploy/releases) page.
45+
46+
To launch, use
47+
48+
```shell
49+
gh-deploy path/to/config.toml
50+
```
51+
52+
### Build from source
53+
54+
```shell
55+
go build -o gh-deploy
56+
```
57+
58+
## Configuration
59+
60+
See [config.example.toml](config.example.toml) for configuration examples.
61+
62+
## License
63+
64+
Contents of this repository are available under [MIT License](LICENSE).

config.example.toml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Server configuration
2+
# bind = "127.0.0.1" # Default is "::" (all IPv4 and IPv6 interfaces)"
3+
port = 8080 # Required
4+
5+
# Enable Git LFS support
6+
# git_lfs = true
7+
8+
# Optional: TLS configuration
9+
# [tls]
10+
# cert_file = "/path/to/cert.pem" # TLS certificate file
11+
# key_file = "/path/to/key.pem" # TLS private key file
12+
13+
# GitHub App configuration
14+
[github_app]
15+
client_id = "123456" # GitHub App client ID
16+
private_key_file = "/path/to/github-app-private-key.pem" # GitHub App private key file
17+
webhook_secret_file = "/path/to/webhook-secret" # File with webhook secret
18+
19+
# Repository definitions
20+
[[repos]]
21+
full_name = "owner/repo"
22+
branch = "main" # Branch to watch for changes
23+
clone_path = "/var/www/repo" # This folder should be writable by user running the gh-deploy
24+
command = "make deploy" # Optional: command to run after update
25+
timeout = 300 # in seconds, default is 120

go.mod

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module gh-deploy
2+
3+
go 1.23.0
4+
5+
toolchain go1.24.1
6+
7+
require (
8+
github.com/BurntSushi/toml v1.5.0
9+
github.com/gofrs/flock v0.12.1
10+
github.com/golang-jwt/jwt/v5 v5.2.3
11+
github.com/google/go-github/v57 v57.0.0
12+
)
13+
14+
require (
15+
github.com/google/go-cmp v0.7.0 // indirect
16+
github.com/google/go-querystring v1.1.0 // indirect
17+
github.com/stretchr/testify v1.10.0 // indirect
18+
golang.org/x/sys v0.34.0 // indirect
19+
)

go.sum

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
2+
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
3+
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
4+
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
5+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
6+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7+
github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=
8+
github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=
9+
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
10+
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
11+
github.com/golang-jwt/jwt/v5 v5.2.3 h1:kkGXqQOBSDDWRhWNXTFpqGSCMyh/PLnqUvMGJPDJDs0=
12+
github.com/golang-jwt/jwt/v5 v5.2.3/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
13+
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
14+
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
15+
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
16+
github.com/google/go-github/v57 v57.0.0 h1:L+Y3UPTY8ALM8x+TV0lg+IEBI+upibemtBD8Q9u7zHs=
17+
github.com/google/go-github/v57 v57.0.0/go.mod h1:s0omdnye0hvK/ecLvpsGfJMiRt85PimQh4oygmLIxHw=
18+
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
19+
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
20+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
21+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
22+
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
23+
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
24+
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
25+
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
26+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
27+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
28+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 commit comments

Comments
 (0)