diff --git a/Cargo.lock b/Cargo.lock index a83ea68..8d56ba9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,30 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -11,6 +35,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "arc-swap" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "983cd8b9d4b02a6dc6ffa557262eb5858a27a0038ffffe21a0f133eaa819a164" + [[package]] name = "async-trait" version = "0.1.58" @@ -39,6 +69,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.13.1" @@ -59,9 +104,9 @@ checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "bytes" -version = "1.2.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "cc" @@ -78,6 +123,22 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-integer", + "num-traits", + "serde", + "time 0.1.45", + "wasm-bindgen", + "winapi", +] + [[package]] name = "clap" version = "2.34.0" @@ -115,6 +176,16 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + [[package]] name = "core-foundation" version = "0.9.3" @@ -131,6 +202,56 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +[[package]] +name = "cxx" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a41a86530d0fe7f5d9ea779916b7cadd2d4f9add748b99c2c029cbbdfaf453" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06416d667ff3e3ad2df1cd8cd8afae5da26cf9cec4d0825040f88b5ca659a2f0" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "820a9a2af1669deeef27cb271f476ffd196a2c4b6731336011e0ba63e2c7cf71" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08a6e2fcc370a089ad3b4aaf54db3b1b4cee38ddabce5896b33eb693275f470" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "dotenv" version = "0.15.0" @@ -212,10 +333,11 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.1.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" dependencies = [ + "matches", "percent-encoding", ] @@ -234,6 +356,17 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +[[package]] +name = "futures-macro" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-sink" version = "0.3.25" @@ -253,9 +386,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ "futures-core", + "futures-macro", "futures-task", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -266,9 +401,15 @@ checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "gimli" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" + [[package]] name = "git2" version = "0.15.0" @@ -330,6 +471,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -426,11 +573,52 @@ dependencies = [ ] [[package]] -name = "idna" -version = "0.3.0" +name = "hyperx" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +checksum = "5617e92fc2f2501c3e2bc6ce547cad841adba2bae5b921c7e52510beca6d084c" dependencies = [ + "base64", + "bytes", + "http", + "httpdate", + "language-tags", + "mime", + "percent-encoding", + "unicase", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", "unicode-bidi", "unicode-normalization", ] @@ -512,6 +700,26 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonwebtoken" +version = "8.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa4b4af834c6cfd35d8763d359661b90f2e45d8f750a0849156c7f4671af09c" +dependencies = [ + "base64", + "pem", + "ring", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "language-tags" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" + [[package]] name = "lazy_static" version = "1.4.0" @@ -564,6 +772,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "link-cplusplus" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] + [[package]] name = "linux-raw-sys" version = "0.1.3" @@ -598,6 +815,12 @@ dependencies = [ "regex-automata", ] +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + [[package]] name = "memchr" version = "2.5.0" @@ -620,6 +843,15 @@ dependencies = [ "unicase", ] +[[package]] +name = "miniz_oxide" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.5" @@ -628,7 +860,7 @@ checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" dependencies = [ "libc", "log", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.42.0", ] @@ -660,6 +892,36 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.13.1" @@ -670,6 +932,41 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +dependencies = [ + "memchr", +] + +[[package]] +name = "octocrab" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db14aefad92da160884fae912983ba22a05afd0437c69d793ac86f639ec7a0fe" +dependencies = [ + "arc-swap", + "async-trait", + "base64", + "bytes", + "cfg-if", + "chrono", + "futures-core", + "futures-util", + "hyperx", + "jsonwebtoken", + "once_cell", + "reqwest", + "secrecy", + "serde", + "serde_json", + "serde_path_to_error", + "snafu", + "url", +] + [[package]] name = "octopush" version = "0.1.0" @@ -703,6 +1000,7 @@ dependencies = [ "git2", "gitea_client", "hex", + "octocrab", "rand", "serde", "serde_yaml", @@ -816,10 +1114,19 @@ dependencies = [ ] [[package]] -name = "percent-encoding" -version = "2.2.0" +name = "pem" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "03c64931a1a212348ec4f3b4362585eca7159d0d09cbdf4a7f74f02173596fd4" +dependencies = [ + "base64", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pin-project-lite" @@ -973,6 +1280,27 @@ dependencies = [ "winreg", ] +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + [[package]] name = "rustix" version = "0.36.3" @@ -1009,6 +1337,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "scratch" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "zeroize", +] + [[package]] name = "security-framework" version = "2.7.0" @@ -1063,6 +1406,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "184c643044780f7ceb59104cef98a5a6f12cb2288a7bc701ab93a362b49fd47d" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1106,6 +1458,18 @@ dependencies = [ "libc", ] +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time 0.3.17", +] + [[package]] name = "slab" version = "0.4.7" @@ -1121,6 +1485,29 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +[[package]] +name = "snafu" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a152ba99b054b22972ee794cf04e5ef572da1229e33b65f3c57abbff0525a454" +dependencies = [ + "backtrace", + "doc-comment", + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5e79cdebbabaebb06a9bdbaedc7f159b410461f63611d4d0e3fb0fab8fed850" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "socket2" version = "0.4.7" @@ -1131,6 +1518,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "strsim" version = "0.8.0" @@ -1186,6 +1579,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thread_local" version = "1.1.4" @@ -1195,6 +1608,44 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "time" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -1396,14 +1847,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1e5fa573d8ac5f1a856f8d7be41d390ee973daf97c806b2c1a465e4e1406e68" [[package]] -name = "url" -version = "2.3.1" +name = "untrusted" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fe195a4f217c25b25cb5058ced57059824a678474874038dc88d211bf508d3" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -1449,6 +1907,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1670,3 +2134,9 @@ checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ "winapi", ] + +[[package]] +name = "zeroize" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" diff --git a/_examples/actions/write_a_readme/dist/bin b/_examples/actions/write_a_readme/dist/bin index a562e14..e3458d0 100755 Binary files a/_examples/actions/write_a_readme/dist/bin and b/_examples/actions/write_a_readme/dist/bin differ diff --git a/_examples/actions/write_a_readme/octopush.yml b/_examples/actions/write_a_readme/octopush.yml index 9d7a62e..b45a24f 100644 --- a/_examples/actions/write_a_readme/octopush.yml +++ b/_examples/actions/write_a_readme/octopush.yml @@ -1,19 +1,19 @@ apiVersion: action name: write-a-readme select: - # github: - # repositories: - # - kjuulh/octopush-test - # push: - # pull-request: - # name: "write a readme" + github: + repositories: + - kjuulh/octopush-test + push: + pull-request: + name: "write a readme" - # gitea: - # repositories: - # - kjuulh/octopush-test - # push: - # pull-request: - # name: "write a readme" + gitea: + repositories: + - kjuulh/octopush-test + push: + pull-request: + name: "write a readme" git: repositories: diff --git a/crates/octopush_cli/src/commands/execute.rs b/crates/octopush_cli/src/commands/execute.rs index 82ad4da..737fe07 100644 --- a/crates/octopush_cli/src/commands/execute.rs +++ b/crates/octopush_cli/src/commands/execute.rs @@ -2,7 +2,10 @@ use std::path::PathBuf; use clap::{Arg, ArgAction, ArgMatches, Command}; use octopush_core::{ - git::{git::LocalGitProviderOptions, gitea::client::DefaultGiteaClientOptions}, + git::{ + git::LocalGitProviderOptions, gitea::client::DefaultGiteaClientOptions, + github::github_client::DefaultGitHubClientOptions, + }, schema, }; use octopush_infra::service_register::ServiceRegister; @@ -41,6 +44,20 @@ pub fn execute_cmd() -> Command { .env("GITEA_URL") .required(false), ) + .arg( + Arg::new("github-api-token") + .long("github-api-token") + .action(ArgAction::Set) + .env("GITHUB_API_TOKEN") + .required(false), + ) + .arg( + Arg::new("github-username") + .long("github-username") + .action(ArgAction::Set) + .env("GITHUB_USERNAME") + .required(false), + ) } pub async fn execute_subcommand(args: &ArgMatches) -> eyre::Result<()> { @@ -52,6 +69,9 @@ pub async fn execute_subcommand(args: &ArgMatches) -> eyre::Result<()> { let gitea_username = args.get_one::("gitea-username"); let gitea_url = args.get_one::("gitea-url"); + let github_http_token = args.get_one::("github-api-token"); + let github_username = args.get_one::("github-username"); + let service_register = ServiceRegister::new( LocalGitProviderOptions { http_auth: None }, DefaultGiteaClientOptions { @@ -61,7 +81,13 @@ pub async fn execute_subcommand(args: &ArgMatches) -> eyre::Result<()> { .map(|(u, ht)| format!("{}:{}", u, ht)) .map(|t| t.clone()), }, - ); + DefaultGitHubClientOptions { + basicauth: github_username + .zip(github_http_token) + .map(|(u, ht)| format!("{}:{}", u, ht)) + .map(|t| t.clone()), + }, + )?; let action_path: PathBuf = action.into(); @@ -91,6 +117,13 @@ pub async fn execute_subcommand(args: &ArgMatches) -> eyre::Result<()> { .run(gitea, &action_path, &action) .await?; } + + if let Some(github) = &select.github { + service_register + .github_selector + .run(github, &action_path, &action) + .await?; + } } } diff --git a/crates/octopush_core/Cargo.toml b/crates/octopush_core/Cargo.toml index ad4e1a2..1c2e0ae 100644 --- a/crates/octopush_core/Cargo.toml +++ b/crates/octopush_core/Cargo.toml @@ -21,3 +21,4 @@ git2 = { version = "0.15.0", features = [ ] } serde = { version = "1.0.147", features = ["derive"] } serde_yaml = "0.9.14" +octocrab = { version = "0.17.0", features = ["futures-core", "futures-util"] } diff --git a/crates/octopush_core/src/git/git.rs b/crates/octopush_core/src/git/git.rs index 8bab12d..a73b548 100644 --- a/crates/octopush_core/src/git/git.rs +++ b/crates/octopush_core/src/git/git.rs @@ -239,9 +239,15 @@ impl GitProvider for LocalGitProvider { remote.fetch(refspec, Some(&mut fo), None)?; - let fetch_head = repo.find_reference("FETCH_HEAD")?; - let commit = repo.reference_to_annotated_commit(&fetch_head)?; - Self::do_merge(&repo, &branch_name, commit)?; + match repo.find_reference("FETCH_HEAD") { + Ok(fetch_head) => { + let commit = repo.reference_to_annotated_commit(&fetch_head)?; + Self::do_merge(&repo, &branch_name, commit)?; + } + Err(e) => { + tracing::info!(error = e.to_string(), "upstream branch not found"); + } + } Ok(()) } diff --git a/crates/octopush_core/src/git/github/github_client.rs b/crates/octopush_core/src/git/github/github_client.rs new file mode 100644 index 0000000..c093833 --- /dev/null +++ b/crates/octopush_core/src/git/github/github_client.rs @@ -0,0 +1,61 @@ +use std::sync::Arc; + +use async_trait::async_trait; +use octocrab::{Octocrab, OctocrabBuilder}; + +use super::GitHubClient; + +pub struct DefaultGitHubClientOptions { + pub basicauth: Option, +} + +pub struct DefaultGitHubClient { + github: Arc, +} + +impl DefaultGitHubClient { + pub fn new(options: &DefaultGitHubClientOptions) -> eyre::Result { + let mut github = OctocrabBuilder::new(); + + if let Some(basicauth) = options.basicauth.clone() { + if let Some((username, password)) = basicauth.split_once(":") { + github = github.basic_auth(username.into(), password.into()); + } + } + + Ok(Self { + github: Arc::new(github.build()?), + }) + } +} + +#[async_trait] +impl GitHubClient for DefaultGitHubClient { + async fn get_clone_url(&self, owner: String, repo_name: String) -> eyre::Result { + let repo = self.github.repos(&owner, &repo_name).get().await?; + let clone_url = repo + .ssh_url + .ok_or(eyre::anyhow!("clone_url is not set for repository"))?; + + Ok(clone_url) + } + + async fn create_pull_request( + &self, + owner: &String, + repo_name: &String, + pull_request_name: &String, + ) -> eyre::Result<()> { + self.github + .pulls(owner, repo_name) + .create( + pull_request_name.clone(), + pull_request_name.to_lowercase().replace(" ", "-"), + "main", + ) + .send() + .await?; + + Ok(()) + } +} diff --git a/crates/octopush_core/src/git/github/github_provider.rs b/crates/octopush_core/src/git/github/github_provider.rs new file mode 100644 index 0000000..4b65b15 --- /dev/null +++ b/crates/octopush_core/src/git/github/github_provider.rs @@ -0,0 +1,79 @@ +use std::{path::PathBuf, sync::Arc}; + +use async_trait::async_trait; +use git2::Repository; +use tokio::sync::Mutex; + +use crate::{git::DynGitProvider, schema::models::GitPushPullRequest, storage::DynStorageEngine}; + +use super::{DynGitHubClient, GitHubProvider}; + +pub struct DefaultGitHubProvider { + git_provider: DynGitProvider, + _storage_engine: DynStorageEngine, + github_client: DynGitHubClient, +} + +impl DefaultGitHubProvider { + pub fn new( + git_provider: DynGitProvider, + storage_engine: DynStorageEngine, + github_client: DynGitHubClient, + ) -> Self { + Self { + git_provider, + _storage_engine: storage_engine, + github_client, + } + } +} + +#[async_trait] +impl GitHubProvider for DefaultGitHubProvider { + async fn clone_from_qualified(&self, repo: &String) -> eyre::Result<(PathBuf, Repository)> { + let (owner, repo_name) = repo + .split_once("/") + .ok_or(eyre::anyhow!("repo is not a valid format"))?; + + let clone_url = self + .github_client + .get_clone_url(owner.into(), repo_name.into()) + .await?; + + let (path, repo) = self.git_provider.clone_from_url(&clone_url).await?; + + Ok((path, repo)) + } + + async fn create_branch( + &self, + repo: Arc>, + pull_request: &GitPushPullRequest, + ) -> eyre::Result<()> { + tracing::trace!("creating branch"); + self.git_provider + .create_branch(repo, &pull_request.name) + .await + } + + async fn create_pull_request( + &self, + repo: Arc>, + repo_name: &String, + pull_request: &GitPushPullRequest, + ) -> eyre::Result<()> { + let (owner, repo_name) = repo_name + .split_once("/") + .ok_or(eyre::anyhow!("repo is not a valid format"))?; + + tracing::trace!("push_branch"); + self.git_provider + .push_branch(repo, &pull_request.name) + .await?; + + tracing::trace!("create_pull_request"); + self.github_client + .create_pull_request(&owner.into(), &repo_name.into(), &pull_request.name) + .await + } +} diff --git a/crates/octopush_core/src/git/github/mod.rs b/crates/octopush_core/src/git/github/mod.rs new file mode 100644 index 0000000..09b280b --- /dev/null +++ b/crates/octopush_core/src/git/github/mod.rs @@ -0,0 +1,42 @@ +pub mod github_client; +pub mod github_provider; + +use std::{path::PathBuf, sync::Arc}; + +use async_trait::async_trait; +use git2::Repository; +use tokio::sync::Mutex; + +use crate::schema::models::GitPushPullRequest; + +#[async_trait] +pub trait GitHubClient { + async fn get_clone_url(&self, owner: String, repo_name: String) -> eyre::Result; + async fn create_pull_request( + &self, + owner: &String, + repo_name: &String, + pull_request_name: &String, + ) -> eyre::Result<()>; +} + +pub type DynGitHubClient = Arc; + +#[async_trait] +pub trait GitHubProvider { + async fn clone_from_qualified(&self, repo: &String) -> eyre::Result<(PathBuf, Repository)>; + async fn create_branch( + &self, + repo: Arc>, + branch: &GitPushPullRequest, + ) -> eyre::Result<()>; + + async fn create_pull_request( + &self, + repo: Arc>, + repo_name: &String, + pull_request: &GitPushPullRequest, + ) -> eyre::Result<()>; +} + +pub type DynGitHubProvider = Arc; diff --git a/crates/octopush_core/src/git/mod.rs b/crates/octopush_core/src/git/mod.rs index 64f58e6..d648c9b 100644 --- a/crates/octopush_core/src/git/mod.rs +++ b/crates/octopush_core/src/git/mod.rs @@ -6,6 +6,7 @@ use tokio::sync::Mutex; pub mod git; pub mod gitea; +pub mod github; #[async_trait] pub trait GitProvider { diff --git a/crates/octopush_core/src/selectors/github_selector.rs b/crates/octopush_core/src/selectors/github_selector.rs new file mode 100644 index 0000000..8b7efef --- /dev/null +++ b/crates/octopush_core/src/selectors/github_selector.rs @@ -0,0 +1,59 @@ +use std::{path::PathBuf, sync::Arc}; + +use tokio::sync::Mutex; + +use crate::{ + executor::executor::DynExecutor, + git::{github::DynGitHubProvider, DynGitProvider}, + schema::models::{Action, GitHub}, +}; + +pub struct GitHubSelector { + github_provider: DynGitHubProvider, + git_provider: DynGitProvider, + executor: DynExecutor, +} + +impl GitHubSelector { + pub fn new( + github_provider: DynGitHubProvider, + git_provider: DynGitProvider, + executor: DynExecutor, + ) -> Self { + Self { + github_provider, + git_provider, + executor, + } + } + + pub async fn run( + &self, + git: &GitHub, + action_path: &PathBuf, + action: &Action, + ) -> eyre::Result<()> { + tracing::info!("fetching repos"); + for repo in &git.repositories { + let gp = self.github_provider.clone(); + let (path, repo) = gp.clone_from_qualified(repo).await?; + let repo = Arc::new(Mutex::new(repo)); + + if let Some(push) = &git.push { + self.git_provider + .create_branch(repo.clone(), &push.pull_request.name) + .await?; + } + + self.executor.execute(&path, action_path, action).await?; + + if let Some(push) = &git.push { + self.git_provider + .push_branch(repo, &push.pull_request.name) + .await?; + } + } + + Ok(()) + } +} diff --git a/crates/octopush_core/src/selectors/mod.rs b/crates/octopush_core/src/selectors/mod.rs index c31befe..c377428 100644 --- a/crates/octopush_core/src/selectors/mod.rs +++ b/crates/octopush_core/src/selectors/mod.rs @@ -1,3 +1,4 @@ pub mod git_selector; pub mod gitea_selector; +pub mod github_selector; diff --git a/crates/octopush_infra/src/service_register.rs b/crates/octopush_infra/src/service_register.rs index 7b0301a..d21f266 100644 --- a/crates/octopush_infra/src/service_register.rs +++ b/crates/octopush_infra/src/service_register.rs @@ -10,10 +10,17 @@ use octopush_core::{ provider::DefaultGiteaProvider, DynGiteaProvider, }, + github::{ + github_client::{DefaultGitHubClient, DefaultGitHubClientOptions}, + github_provider::DefaultGitHubProvider, + DynGitHubProvider, + }, DynGitProvider, }, schema::parser::{DefaultSchemaParser, DynSchemaParser}, - selectors::{git_selector::GitSelector, gitea_selector::GiteaSelector}, + selectors::{ + git_selector::GitSelector, gitea_selector::GiteaSelector, github_selector::GitHubSelector, + }, storage::{local::LocalStorageEngine, DynStorageEngine}, }; @@ -26,13 +33,16 @@ pub struct ServiceRegister { pub gitea_provider: DynGiteaProvider, pub git_selector: Arc, pub gitea_selector: Arc, + pub github_provider: DynGitHubProvider, + pub github_selector: Arc, } impl ServiceRegister { pub fn new( git_provider_options: LocalGitProviderOptions, gitea_client_options: DefaultGiteaClientOptions, - ) -> Self { + github_client_options: DefaultGitHubClientOptions, + ) -> eyre::Result { let storage_engine = Arc::new(LocalStorageEngine::new("/tmp/octopush".into())); let git_provider = Arc::new(LocalGitProvider::new( git_provider_options, @@ -53,8 +63,19 @@ impl ServiceRegister { git_provider.clone(), executor.clone(), )); + let github_client = Arc::new(DefaultGitHubClient::new(&github_client_options)?); + let github_provider = Arc::new(DefaultGitHubProvider::new( + git_provider.clone(), + storage_engine.clone(), + github_client.clone(), + )); + let github_selector = Arc::new(GitHubSelector::new( + github_provider.clone(), + git_provider.clone(), + executor.clone(), + )); - Self { + Ok(Self { storage_engine, git_provider, schema_parser, @@ -63,7 +84,9 @@ impl ServiceRegister { gitea_provider, git_selector, gitea_selector, - } + github_provider, + github_selector, + }) } pub async fn cleanup(self) -> eyre::Result<()> {