mirror of
https://git.sr.ht/~ashkeel/sourcehut-mirror-bridge
synced 2024-12-21 22:32:19 +00:00
Compare commits
2 commits
461d015a1d
...
02fc03878d
Author | SHA1 | Date | |
---|---|---|---|
|
02fc03878d | ||
|
7058bf90b2 |
10 changed files with 438 additions and 173 deletions
4
.dockerignore
Normal file
4
.dockerignore
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
target
|
||||||
|
LICENSE
|
||||||
|
README.md
|
||||||
|
.env
|
43
.drone.yml
Normal file
43
.drone.yml
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: default
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: publish sha
|
||||||
|
image: banzaicloud/drone-kaniko
|
||||||
|
settings:
|
||||||
|
registry: registry.fromouter.space
|
||||||
|
repo: uchumoe/sourcehut-mirror-bridge
|
||||||
|
cache: true
|
||||||
|
username:
|
||||||
|
from_secret: docker_username
|
||||||
|
password:
|
||||||
|
from_secret: docker_password
|
||||||
|
tags:
|
||||||
|
- latest
|
||||||
|
- ${DRONE_COMMIT_SHA}
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
|
||||||
|
- name: publish tag
|
||||||
|
image: banzaicloud/drone-kaniko
|
||||||
|
settings:
|
||||||
|
registry: registry.fromouter.space
|
||||||
|
repo: uchumoe/sourcehut-mirror-bridge
|
||||||
|
cache: true
|
||||||
|
username:
|
||||||
|
from_secret: docker_username
|
||||||
|
password:
|
||||||
|
from_secret: docker_password
|
||||||
|
tags:
|
||||||
|
- ${DRONE_COMMIT_BRANCH}
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- tag
|
||||||
|
---
|
||||||
|
kind: signature
|
||||||
|
hmac: 925643c1816fd7df3823079bc98a79836e34e4641b8328ae0bc3eae37923ff84
|
||||||
|
|
||||||
|
...
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
/target
|
/target
|
||||||
|
.env
|
296
Cargo.lock
generated
296
Cargo.lock
generated
|
@ -68,6 +68,15 @@ dependencies = [
|
||||||
"opaque-debug",
|
"opaque-debug",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aliasable"
|
name = "aliasable"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
@ -177,7 +186,7 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"parking",
|
"parking",
|
||||||
"polling",
|
"polling",
|
||||||
"rustix",
|
"rustix 0.37.27",
|
||||||
"slab",
|
"slab",
|
||||||
"socket2",
|
"socket2",
|
||||||
"waker-fn",
|
"waker-fn",
|
||||||
|
@ -271,6 +280,12 @@ version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
name = "block-buffer"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
@ -360,18 +375,6 @@ dependencies = [
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "console"
|
|
||||||
version = "0.15.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8"
|
|
||||||
dependencies = [
|
|
||||||
"encode_unicode",
|
|
||||||
"lazy_static",
|
|
||||||
"libc",
|
|
||||||
"windows-sys 0.45.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const_fn"
|
name = "const_fn"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
|
@ -456,6 +459,16 @@ dependencies = [
|
||||||
"cipher",
|
"cipher",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ctrlc"
|
||||||
|
version = "3.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "82e95fbd621905b854affdc67943b043a0fbb6ed7385fd5a25650d19a8a6cfdf"
|
||||||
|
dependencies = [
|
||||||
|
"nix",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cynic"
|
name = "cynic"
|
||||||
version = "3.2.2"
|
version = "3.2.2"
|
||||||
|
@ -550,6 +563,12 @@ version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dotenvy"
|
||||||
|
version = "0.15.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
|
@ -557,10 +576,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encode_unicode"
|
name = "env_logger"
|
||||||
version = "0.3.6"
|
version = "0.10.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece"
|
||||||
|
dependencies = [
|
||||||
|
"humantime",
|
||||||
|
"is-terminal",
|
||||||
|
"log",
|
||||||
|
"regex",
|
||||||
|
"termcolor",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "envy"
|
name = "envy"
|
||||||
|
@ -578,7 +604,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e"
|
checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -826,6 +852,12 @@ version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "humantime"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ident_case"
|
name = "ident_case"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -848,19 +880,6 @@ version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "64e9829a50b42bb782c1df523f78d332fe371b10c661e78b7a3c34b0198e9fac"
|
checksum = "64e9829a50b42bb782c1df523f78d332fe371b10c661e78b7a3c34b0198e9fac"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "insta"
|
|
||||||
version = "1.34.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5d64600be34b2fcfc267740a243fa7744441bb4947a619ac4e5bb6507f35fbfc"
|
|
||||||
dependencies = [
|
|
||||||
"console",
|
|
||||||
"lazy_static",
|
|
||||||
"linked-hash-map",
|
|
||||||
"similar",
|
|
||||||
"yaml-rust",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "instant"
|
name = "instant"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
|
@ -878,7 +897,18 @@ checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is-terminal"
|
||||||
|
version = "0.4.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"rustix 0.38.21",
|
||||||
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -905,30 +935,24 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lazy_static"
|
|
||||||
version = "1.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.150"
|
version = "0.2.150"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "linked-hash-map"
|
|
||||||
version = "0.5.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
|
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.4.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.20"
|
version = "0.4.20"
|
||||||
|
@ -969,6 +993,17 @@ dependencies = [
|
||||||
"adler",
|
"adler",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.27.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.4.1",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.17"
|
version = "0.2.17"
|
||||||
|
@ -1055,13 +1090,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
|
checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"concurrent-queue",
|
"concurrent-queue",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1220,6 +1255,35 @@ dependencies = [
|
||||||
"syn 2.0.39",
|
"syn 2.0.39",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.17.5"
|
version = "0.17.5"
|
||||||
|
@ -1231,7 +1295,7 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"spin",
|
"spin",
|
||||||
"untrusted",
|
"untrusted",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1249,12 +1313,25 @@ version = "0.37.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2"
|
checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"errno",
|
"errno",
|
||||||
"io-lifetimes",
|
"io-lifetimes",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys 0.3.8",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustix"
|
||||||
|
version = "0.38.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.4.1",
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys 0.4.11",
|
||||||
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1398,12 +1475,6 @@ dependencies = [
|
||||||
"opaque-debug",
|
"opaque-debug",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "similar"
|
|
||||||
version = "2.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2aeaf503862c419d66959f5d7ca015337d864e9c49485d771b732e2a20453597"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
|
@ -1429,10 +1500,14 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"argh",
|
"argh",
|
||||||
|
"base64 0.21.5",
|
||||||
|
"ctrlc",
|
||||||
"cynic",
|
"cynic",
|
||||||
"cynic-codegen",
|
"cynic-codegen",
|
||||||
|
"dotenvy",
|
||||||
|
"env_logger",
|
||||||
"envy",
|
"envy",
|
||||||
"insta",
|
"log",
|
||||||
"semver 1.0.20",
|
"semver 1.0.20",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -1564,6 +1639,15 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "termcolor"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.50"
|
version = "1.0.50"
|
||||||
|
@ -1890,43 +1974,28 @@ version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-util"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.45.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
|
||||||
dependencies = [
|
|
||||||
"windows-targets 0.42.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets 0.48.5",
|
"windows-targets",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-targets"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm 0.42.2",
|
|
||||||
"windows_aarch64_msvc 0.42.2",
|
|
||||||
"windows_i686_gnu 0.42.2",
|
|
||||||
"windows_i686_msvc 0.42.2",
|
|
||||||
"windows_x86_64_gnu 0.42.2",
|
|
||||||
"windows_x86_64_gnullvm 0.42.2",
|
|
||||||
"windows_x86_64_msvc 0.42.2",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1935,104 +2004,53 @@ version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_gnullvm 0.48.5",
|
"windows_aarch64_gnullvm",
|
||||||
"windows_aarch64_msvc 0.48.5",
|
"windows_aarch64_msvc",
|
||||||
"windows_i686_gnu 0.48.5",
|
"windows_i686_gnu",
|
||||||
"windows_i686_msvc 0.48.5",
|
"windows_i686_msvc",
|
||||||
"windows_x86_64_gnu 0.48.5",
|
"windows_x86_64_gnu",
|
||||||
"windows_x86_64_gnullvm 0.48.5",
|
"windows_x86_64_gnullvm",
|
||||||
"windows_x86_64_msvc 0.48.5",
|
"windows_x86_64_msvc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_gnullvm"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_gnullvm"
|
name = "windows_aarch64_gnullvm"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_msvc"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_msvc"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnu"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnullvm"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_msvc"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.48.5"
|
version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "yaml-rust"
|
|
||||||
version = "0.4.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
|
||||||
dependencies = [
|
|
||||||
"linked-hash-map",
|
|
||||||
]
|
|
||||||
|
|
|
@ -7,14 +7,18 @@ license = "AGPL-3.0-only"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
argh = "0.1"
|
argh = "0.1"
|
||||||
|
base64 = "0.21.5"
|
||||||
|
ctrlc = { version = "3", features = ["termination"] }
|
||||||
cynic = { version = "3", features = ["http-surf"] }
|
cynic = { version = "3", features = ["http-surf"] }
|
||||||
|
dotenvy = "0.15"
|
||||||
envy = "0.4"
|
envy = "0.4"
|
||||||
semver = "1"
|
semver = "1"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
tiny_http = "0.12"
|
tiny_http = "0.12"
|
||||||
|
log = "0.4"
|
||||||
|
env_logger = "0.10"
|
||||||
ureq = { version = "2", features = ["json"] }
|
ureq = { version = "2", features = ["json"] }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cynic-codegen = { version = "3" }
|
cynic-codegen = { version = "3" }
|
||||||
insta = "1"
|
|
||||||
|
|
20
Dockerfile
Normal file
20
Dockerfile
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
FROM public.ecr.aws/docker/library/rust:1-alpine as builder
|
||||||
|
|
||||||
|
RUN rustup default stable
|
||||||
|
RUN apk add --no-cache musl-dev openssl-dev openssl-libs-static pkgconf git
|
||||||
|
|
||||||
|
# Set `SYSROOT` to a dummy path (default is /usr) because pkg-config-rs *always*
|
||||||
|
# links those located in that path dynamically but we want static linking, c.f.
|
||||||
|
# https://github.com/rust-lang/pkg-config-rs/blob/54325785816695df031cef3b26b6a9a203bbc01b/src/lib.rs#L613
|
||||||
|
ENV SYSROOT=/dummy
|
||||||
|
|
||||||
|
WORKDIR /wd
|
||||||
|
COPY . /wd
|
||||||
|
RUN cargo build --release --target=x86_64-unknown-linux-musl
|
||||||
|
|
||||||
|
FROM public.ecr.aws/docker/library/alpine
|
||||||
|
ARG version=unknown
|
||||||
|
ARG release=unreleased
|
||||||
|
|
||||||
|
COPY --from=builder /wd/target/x86_64-unknown-linux-musl/release/sourcehut-mirror-bridge /usr/local/bin/
|
||||||
|
CMD ["sourcehut-mirror-bridge"]
|
5
README.md
Normal file
5
README.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# sourcehut-mirror-bridge
|
||||||
|
|
||||||
|
SourceHut to Gitea active mirror bridge. Uses Soucehut GQL APIs to set up a webhook and manually sync a downstream Gitea/Forgejo repository set as a mirror.
|
||||||
|
|
||||||
|
Use case: You're running Drone CI or others linked to a Gitea instance and you want them to run as soon as possible.
|
49
src/gitea.rs
Normal file
49
src/gitea.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
use anyhow::Result;
|
||||||
|
use base64::{engine::general_purpose, Engine as _};
|
||||||
|
use log::debug;
|
||||||
|
|
||||||
|
pub struct GiteaAPI {
|
||||||
|
api_endpoint: String,
|
||||||
|
auth: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GiteaAPI {
|
||||||
|
pub fn new(api_endpoint: &str, auth: &str) -> Self {
|
||||||
|
Self {
|
||||||
|
api_endpoint: api_endpoint.to_string(),
|
||||||
|
auth: basic_auth(auth),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_repositories(&self, project_ids: &[&str]) -> Result<()> {
|
||||||
|
for repo in project_ids {
|
||||||
|
let api_url = format!("{}/v1/repos/{}", self.api_endpoint, repo);
|
||||||
|
let res = ureq::get(&api_url)
|
||||||
|
.set("Authorization", &self.auth)
|
||||||
|
.call()?;
|
||||||
|
if res.status() != 200 {
|
||||||
|
let body = res.into_string()?;
|
||||||
|
return Err(anyhow::anyhow!(
|
||||||
|
"Error fetching repository {}: {}",
|
||||||
|
repo,
|
||||||
|
body
|
||||||
|
));
|
||||||
|
}
|
||||||
|
debug!("Repository {} exists", repo);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sync(&self, project_id: &str) -> Result<()> {
|
||||||
|
let api_url = format!("{}/v1/repos/{}/mirror-sync", &self.api_endpoint, project_id);
|
||||||
|
ureq::post(&api_url)
|
||||||
|
.set("Authorization", &self.auth)
|
||||||
|
.call()?;
|
||||||
|
debug!("Synced repository {}", project_id);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn basic_auth(auth: &str) -> String {
|
||||||
|
format!("Basic {}", general_purpose::STANDARD.encode(auth))
|
||||||
|
}
|
109
src/main.rs
109
src/main.rs
|
@ -1,8 +1,14 @@
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
use gitea::GiteaAPI;
|
||||||
|
use log::{debug, error, info};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use tiny_http::{Header, Server};
|
use std::{collections::HashMap, process::exit, sync::Arc};
|
||||||
|
use tiny_http::{Request, Response, Server};
|
||||||
|
|
||||||
mod webhook;
|
use crate::sourcehut::SourcehutAPI;
|
||||||
|
|
||||||
|
mod gitea;
|
||||||
|
mod sourcehut;
|
||||||
|
|
||||||
fn default_bind() -> String {
|
fn default_bind() -> String {
|
||||||
"0.0.0.0:8000".to_string()
|
"0.0.0.0:8000".to_string()
|
||||||
|
@ -14,33 +20,120 @@ fn default_sourcehut_api() -> String {
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
struct Config {
|
struct Config {
|
||||||
|
/// Bind address
|
||||||
#[serde(default = "default_bind")]
|
#[serde(default = "default_bind")]
|
||||||
bind: String,
|
bind: String,
|
||||||
|
|
||||||
|
/// Sourcehut API endpoint
|
||||||
#[serde(default = "default_sourcehut_api")]
|
#[serde(default = "default_sourcehut_api")]
|
||||||
sourcehut_api: String,
|
sourcehut_api: String,
|
||||||
|
|
||||||
|
/// Sourcehut API token (from https://meta.sr.ht/oauth2, needs `git.sr.ht/REPOSITORY` grant)
|
||||||
|
#[serde(default = "default_sourcehut_api")]
|
||||||
sourcehut_token: String,
|
sourcehut_token: String,
|
||||||
|
|
||||||
|
/// Base URL for Gitea API (without the /v1)
|
||||||
gitea_api_base: String,
|
gitea_api_base: String,
|
||||||
|
/// username:password for basic auth
|
||||||
gitea_auth: String,
|
gitea_auth: String,
|
||||||
|
|
||||||
|
/// URL to set as sourcehut webhook target where this service is reacheable
|
||||||
url: String,
|
url: String,
|
||||||
|
|
||||||
|
/// Comma separated list of repository map from sourcehut to Gitea e.g. "sourcehutrepo:owner/gitearepo"
|
||||||
repositories: String,
|
repositories: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
|
let _ = dotenvy::dotenv();
|
||||||
|
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
let config = envy::prefixed("MIRROR_").from_env::<Config>()?;
|
let config = envy::prefixed("MIRROR_").from_env::<Config>()?;
|
||||||
|
|
||||||
|
// Parse repository mapping into a hashmap
|
||||||
|
let repository_map: HashMap<&str, &str> = config
|
||||||
|
.repositories
|
||||||
|
.split(",")
|
||||||
|
.map(|s| s.split_once(":").unwrap())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if repository_map.is_empty() {
|
||||||
|
return Err(anyhow!("No repositories provided"));
|
||||||
|
}
|
||||||
|
|
||||||
|
debug!("Repository map: {:?}", repository_map);
|
||||||
|
|
||||||
|
// Set up Gitea API and check that provided repositories exist
|
||||||
|
let gitea = GiteaAPI::new(&config.gitea_api_base, &config.gitea_auth);
|
||||||
|
let repositories = repository_map.values().map(|&s| s).collect::<Vec<_>>();
|
||||||
|
gitea.check_repositories(&repositories)?;
|
||||||
|
|
||||||
// Set up webhooks via GQL API to sourcehut
|
// Set up webhooks via GQL API to sourcehut
|
||||||
let mut srht_api = webhook::SourceHutAPI::new(&config.sourcehut_api, &config.sourcehut_token);
|
let mut srht = SourcehutAPI::new(&config.sourcehut_api, &config.sourcehut_token);
|
||||||
srht_api.init_webhook(&config.url)?;
|
srht.init_webhook(&config.url)?;
|
||||||
|
|
||||||
|
let api = Arc::new(srht);
|
||||||
|
let r = api.clone();
|
||||||
|
|
||||||
|
// Set up termination handler to delete webhook
|
||||||
|
ctrlc::set_handler(move || {
|
||||||
|
_ = r.delete_webhook();
|
||||||
|
exit(0)
|
||||||
|
})
|
||||||
|
.expect("Error setting termination handler");
|
||||||
|
|
||||||
|
// Listen for webhooks and handle them
|
||||||
let server = Server::http(config.bind).map_err(|err| anyhow!(err))?;
|
let server = Server::http(config.bind).map_err(|err| anyhow!(err))?;
|
||||||
|
for request in server.incoming_requests() {
|
||||||
let json = Header::from_bytes(&b"Content-Type"[..], &b"application/json"[..]).unwrap();
|
debug!("Received request from {:?}", request.remote_addr());
|
||||||
|
match handle_request(request) {
|
||||||
for request in server.incoming_requests() {}
|
Ok(Some(repository)) => {
|
||||||
|
// Get mapped repository, if it exists
|
||||||
|
if let Some(mapped) = repository_map.get(repository.as_str()) {
|
||||||
|
info!("Syncing repository {}", mapped);
|
||||||
|
if let Err(err) = gitea.sync(&mapped) {
|
||||||
|
error!("Error syncing repository: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
error!("Error handling webhook: {}", err);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// Invalid request, ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_request(mut request: Request) -> Result<Option<String>> {
|
||||||
|
// Make sure the content type is JSON
|
||||||
|
let is_json = request
|
||||||
|
.headers()
|
||||||
|
.iter()
|
||||||
|
.find(|h| h.field.as_str() == "Content-Type" && h.value == "application/json")
|
||||||
|
.ok_or_else(|| anyhow!("Invalid Content-Type header"));
|
||||||
|
|
||||||
|
match is_json {
|
||||||
|
Ok(_) => {
|
||||||
|
let mut content = String::new();
|
||||||
|
request.as_reader().read_to_string(&mut content)?;
|
||||||
|
let repository = SourcehutAPI::read_webhook_payload(&content)?;
|
||||||
|
request.respond(Response::empty(204))?;
|
||||||
|
|
||||||
|
return Ok(Some(repository.name));
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
debug!(
|
||||||
|
"Rejecting request because of invalid Content-Type header: {}",
|
||||||
|
err
|
||||||
|
);
|
||||||
|
request.respond(Response::from_string(err.to_string()).with_status_code(400))?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cynic::{GraphQlResponse, MutationBuilder};
|
use cynic::{GraphQlResponse, MutationBuilder};
|
||||||
|
use log::error;
|
||||||
|
|
||||||
#[cynic::schema("sourcehut")]
|
#[cynic::schema("sourcehut")]
|
||||||
mod schema {}
|
mod schema {}
|
||||||
|
@ -14,13 +15,9 @@ struct CreateWebhookVariables {
|
||||||
struct CreateWebhook {
|
struct CreateWebhook {
|
||||||
#[arguments(config: { events: ["REPO_UPDATE"], query: r#"query {
|
#[arguments(config: { events: ["REPO_UPDATE"], query: r#"query {
|
||||||
webhook {
|
webhook {
|
||||||
uuid
|
|
||||||
event
|
|
||||||
date
|
|
||||||
... on RepositoryEvent {
|
... on RepositoryEvent {
|
||||||
repository {
|
repository {
|
||||||
name
|
name
|
||||||
updated
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,18 +39,44 @@ struct DeleteWebhookVariables {
|
||||||
#[cynic(graphql_type = "Mutation", variables = "DeleteWebhookVariables")]
|
#[cynic(graphql_type = "Mutation", variables = "DeleteWebhookVariables")]
|
||||||
struct DeleteWebhook {
|
struct DeleteWebhook {
|
||||||
#[arguments(id: $id)]
|
#[arguments(id: $id)]
|
||||||
|
#[allow(dead_code)]
|
||||||
delete_user_webhook: WebhookSubscription,
|
delete_user_webhook: WebhookSubscription,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SourceHutAPI {
|
#[derive(cynic::QueryFragment, Debug)]
|
||||||
|
struct RepositoryEvent {
|
||||||
|
repository: Repository,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::QueryFragment, Debug)]
|
||||||
|
pub struct Repository {
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize, Debug)]
|
||||||
|
struct WebhookEventReceived {
|
||||||
|
webhook: RepositoryEvent,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::Enum, Clone, Copy, Debug)]
|
||||||
|
enum WebhookEvent {
|
||||||
|
RepoCreated,
|
||||||
|
RepoUpdate,
|
||||||
|
RepoDeleted,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(cynic::Scalar, Debug, Clone)]
|
||||||
|
pub struct Time(pub String);
|
||||||
|
|
||||||
|
pub struct SourcehutAPI {
|
||||||
api_endpoint: String,
|
api_endpoint: String,
|
||||||
token: String,
|
token: String,
|
||||||
webhook_id: Option<i32>,
|
webhook_id: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_gql_response(response: GraphQlResponse<WebhookSubscription>) -> Result<i32> {
|
fn parse_gql_response<T>(response: GraphQlResponse<T>) -> Result<T> {
|
||||||
match response.data {
|
match response.data {
|
||||||
Some(data) => Ok(data.id),
|
Some(data) => Ok(data),
|
||||||
None => {
|
None => {
|
||||||
// Check for errors
|
// Check for errors
|
||||||
match response.errors {
|
match response.errors {
|
||||||
|
@ -68,7 +91,7 @@ fn parse_gql_response(response: GraphQlResponse<WebhookSubscription>) -> Result<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SourceHutAPI {
|
impl SourcehutAPI {
|
||||||
pub fn new(api_endpoint: &str, token: &str) -> Self {
|
pub fn new(api_endpoint: &str, token: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
api_endpoint: api_endpoint.to_string(),
|
api_endpoint: api_endpoint.to_string(),
|
||||||
|
@ -83,32 +106,37 @@ impl SourceHutAPI {
|
||||||
});
|
});
|
||||||
let response = ureq::post(&self.api_endpoint)
|
let response = ureq::post(&self.api_endpoint)
|
||||||
.set("Authorization", &format!("Bearer {}", &self.token))
|
.set("Authorization", &format!("Bearer {}", &self.token))
|
||||||
.send_json(&operation)?
|
.send_json(operation)?
|
||||||
.into_json::<GraphQlResponse<WebhookSubscription>>()?;
|
.into_json::<GraphQlResponse<CreateWebhook>>()?;
|
||||||
|
|
||||||
let webhook_id = parse_gql_response(response)?;
|
|
||||||
self.webhook_id = Some(webhook_id);
|
|
||||||
|
|
||||||
|
let webhook_ev = parse_gql_response(response)?;
|
||||||
|
self.webhook_id = Some(webhook_ev.create_user_webhook.id);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_webhook(&self, id: i32) -> Result<i32> {
|
pub fn delete_webhook(&self) -> Result<()> {
|
||||||
let operation = DeleteWebhook::build(DeleteWebhookVariables { id });
|
if let Some(id) = self.webhook_id {
|
||||||
let response = ureq::post(&self.api_endpoint)
|
let operation = DeleteWebhook::build(DeleteWebhookVariables { id });
|
||||||
.set("Authorization", &format!("Bearer {}", &self.token))
|
let response = ureq::post(&self.api_endpoint)
|
||||||
.send_json(&operation)?
|
.set("Authorization", &format!("Bearer {}", &self.token))
|
||||||
.into_json::<GraphQlResponse<WebhookSubscription>>()?;
|
.send_json(operation)?
|
||||||
|
.into_json::<GraphQlResponse<DeleteWebhook>>()?;
|
||||||
|
|
||||||
parse_gql_response(response)
|
parse_gql_response(response)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_webhook_payload(data: &str) -> Result<Repository> {
|
||||||
|
let data = serde_json::from_str::<GraphQlResponse<WebhookEventReceived>>(data)?;
|
||||||
|
parse_gql_response(data).map(|ev| ev.webhook.repository)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for SourceHutAPI {
|
impl Drop for SourcehutAPI {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if let Some(id) = self.webhook_id {
|
if let Err(e) = self.delete_webhook() {
|
||||||
if let Err(e) = self.delete_webhook(id) {
|
error!("Failed to delete webhook: {}", e);
|
||||||
println!("Failed to delete webhook: {}", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue