diff --git a/.gitignore b/.gitignore index 37c8717f..9dbca849 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target **/*.rs.bk .env +/db/ diff --git a/Cargo.lock b/Cargo.lock index ef0fa9e9..883566ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,17 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "0.7.18" @@ -467,6 +478,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fastrand" version = "1.7.0" @@ -704,7 +721,7 @@ dependencies = [ "indexmap", "slab", "tokio", - "tokio-util 0.7.1", + "tokio-util", "tracing", ] @@ -714,6 +731,24 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashlink" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa" +dependencies = [ + "hashbrown 0.12.3", +] + [[package]] name = "hermit-abi" version = "0.1.19" @@ -867,7 +902,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.11.2", "serde", ] @@ -928,6 +963,17 @@ version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd" +[[package]] +name = "libsqlite3-sys" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "lock_api" version = "0.4.7" @@ -1171,27 +1217,25 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.11.2" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ - "instant", "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" -version = "0.8.5" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", - "instant", "libc", "redox_syscall", "smallvec", - "winapi", + "windows-sys", ] [[package]] @@ -1254,18 +1298,18 @@ dependencies = [ [[package]] name = "phf" -version = "0.10.1" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" dependencies = [ "phf_shared", ] [[package]] name = "phf_shared" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" dependencies = [ "siphasher", ] @@ -1363,7 +1407,8 @@ dependencies = [ "postgres-protocol", "serde", "serde_json", - "uuid", + "uuid 0.8.2", + "uuid 1.3.0", ] [[package]] @@ -1529,6 +1574,23 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" +[[package]] +name = "rusqlite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" +dependencies = [ + "bitflags", + "chrono", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "serde_json", + "smallvec", + "uuid 1.3.0", +] + [[package]] name = "rust_team_data" version = "1.0.0" @@ -1917,15 +1979,16 @@ dependencies = [ [[package]] name = "tokio-postgres" -version = "0.7.5" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6c8b33df661b548dcd8f9bf87debb8c56c05657ed291122e1188698c2ece95" +checksum = "29a12c1b3e0704ae7dfc25562629798b29c72e6b1d0a681b6f29ab4ae5e7f7bf" dependencies = [ "async-trait", "byteorder", "bytes", "fallible-iterator", - "futures", + "futures-channel", + "futures-util", "log", "parking_lot", "percent-encoding", @@ -1935,21 +1998,7 @@ dependencies = [ "postgres-types", "socket2", "tokio", - "tokio-util 0.6.9", -] - -[[package]] -name = "tokio-util" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", + "tokio-util", ] [[package]] @@ -1986,7 +2035,7 @@ dependencies = [ "pin-project", "pin-project-lite", "tokio", - "tokio-util 0.7.1", + "tokio-util", "tower-layer", "tower-service", "tracing", @@ -2073,6 +2122,7 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", + "bytes", "chrono", "comrak", "cron", @@ -2097,6 +2147,7 @@ dependencies = [ "regex", "reqwest", "route-recognizer", + "rusqlite", "rust_team_data", "serde", "serde_json", @@ -2109,7 +2160,7 @@ dependencies = [ "tracing", "tracing-subscriber", "url", - "uuid", + "uuid 1.3.0", ] [[package]] @@ -2271,6 +2322,12 @@ name = "uuid" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" + +[[package]] +name = "uuid" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" dependencies = [ "getrandom", "serde", @@ -2446,6 +2503,72 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" + [[package]] name = "winreg" version = "0.10.1" diff --git a/Cargo.toml b/Cargo.toml index 26780fa6..15decd9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ hyper = { version = "0.14.4", features = ["server", "stream"]} tokio = { version = "1.7.1", features = ["macros", "time", "rt"] } futures = { version = "0.3", default-features = false, features = ["std"] } async-trait = "0.1.31" -uuid = { version = "0.8", features = ["v4", "serde"] } +uuid = { version = "1.3", features = ["v4", "serde"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } url = "2.1.0" @@ -42,8 +42,10 @@ tower = { version = "0.4.13", features = ["util", "limit", "buffer", "load-shed" github-graphql = { path = "github-graphql" } rand = "0.8.5" ignore = "0.4.18" -postgres-types = { version = "0.2.4", features = ["derive"] } +postgres-types = { version = "0.2.4", features = ["derive", "with-uuid-1"] } cron = { version = "0.12.0" } +bytes = "1.1.0" +rusqlite = { version = "0.28.0", features = ["bundled", "chrono", "serde_json", "uuid"] } [dependencies.serde] version = "1" diff --git a/Dockerfile b/Dockerfile index dbd7084b..f9495286 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,12 +18,19 @@ RUN apt-get update -y && \ pkg-config \ git \ cmake \ - zlib1g-dev + zlib1g-dev \ + postgresql + +# postgres does not allow running as root +RUN groupadd -r builder && useradd -m -r -g builder builder +USER builder RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- \ --default-toolchain stable --profile minimal -y -COPY . . +COPY --chown=builder . /triagebot +WORKDIR /triagebot + RUN bash -c 'source $HOME/.cargo/env && cargo test --release --all' RUN bash -c 'source $HOME/.cargo/env && cargo build --release' @@ -38,7 +45,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ RUN mkdir -p /opt/triagebot -COPY --from=build /target/release/triagebot /usr/local/bin/ +COPY --from=build /triagebot/target/release/triagebot /usr/local/bin/ COPY templates /opt/triagebot/templates WORKDIR /opt/triagebot ENV PORT=80 diff --git a/README.md b/README.md index 69983c48..8d12aefb 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ The Triagebot webserver also includes several other endpoints intended for users Triagebot uses a Postgres database to retain some state. In production, it uses [RDS](https://aws.amazon.com/rds/). +For local testing you can use SQLite (see below). The server at https://triage.rust-lang.org/ runs on ECS and is configured via [Terraform](https://github.com/rust-lang/simpleinfra/blob/master/terraform/shared/services/triagebot/main.tf#L8). Updates are automatically deployed when merged to master. @@ -34,38 +35,117 @@ Some developers may settle with testing in production as the risks tend to be lo The general overview of what you will need to do: +1. Create a repo on GitHub to run tests on. +2. [Configure a database](#configure-a-database) +3. [Configure webhook forwarding](#configure-webhook-forwarding) +4. Configure the `.env` file: + + 1. Copy `.env.sample` to `.env` + 2. `GITHUB_API_TOKEN`: This is a token needed for Triagebot to send requests to GitHub. Go to GitHub Settings > Developer Settings > Personal Access Token, and create a new token. The `repo` permission should be sufficient. + If this is not set, Triagebot will also look in `~/.gitconfig` in the `github.oauth-token` setting. + 3. `DATABASE_URL`: This is the URL to the database. See [Configuring a database](#configuring-a-database). + 4. `GITHUB_WEBHOOK_SECRET`: Enter the secret you entered in the webhook above. + 5. `RUST_LOG`: Set this to `debug`. + +5. Run `cargo run --bin triagebot`. This starts the http server listening for webhooks on port 8000. +6. Add a `triagebot.toml` file to the main branch of your GitHub repo with whichever services you want to try out. +7. Try interacting with your repo, such as issuing `@rustbot` commands or interacting with PRs and issues (depending on which services you enabled in `triagebot.toml`). Watch the logs from the server to see what's going on. + +### Configure a database + +For testing, it is probably easiest to use SQLite. +If you want something closer to production, then you might want to set up Postgres. + +#### SQLite + +To use SQLite, all you need to do is in the `.env` file set `DATABASE_URL` to a file: + +```bash +DATABASE_URL=db/triagebot.sqlite +``` + +If you have the [`sqlite3` CLI program](https://sqlite.org/cli.html) installed, you can use that to interactively run queries against the database with `sqlite3 db/triagebot.sqlite`. + +#### Postgres + +To use Postgres, you will need to install it and configure it: + 1. Install Postgres. Look online for any help with installing and setting up Postgres (particularly if you need to create a user and set up permissions). 2. Create a database: `createdb triagebot` -3. Provide a way for GitHub to access the Triagebot webserver. - There are various ways to do this (such as placing it behind a proxy, or poking holes in your firewall). - Or, you can use a service such as https://ngrok.com/ to access on your local dev machine via localhost. - Installation is fairly simple, though requires setting up a (free) account. - Run the command `ngrok http 8000` to forward to port 8000 on localhost. -4. Create a GitHub repo to run some tests on. -5. Configure the webhook in your GitHub repo. - I recommend at least skimming the [GitHub webhook documentation](https://docs.github.com/en/developers/webhooks-and-events/webhooks/about-webhooks) if you are not familiar with webhooks. In short: - - 1. Go to the settings page. +3. In the `.env` file, set the `DATABASE_URL`: + + ```sh + DATABASE_URL=postgres://eric@localhost/triagebot + ``` + + replacing `eric` with the username on your local system. + +### Configure webhook forwarding + +I recommend at least skimming the [GitHub webhook documentation](https://docs.github.com/en/developers/webhooks-and-events/webhooks/about-webhooks) if you are not familiar with webhooks. +In order for GitHub's webhooks to reach your triagebot server, you'll need to figure out some way to route them to your machine. +There are various options on how to do this. +You can poke holes into your firewall or use a proxy, but you shouldn't expose your machine to the the internet. +There are various services which help with this problem. +These generally involve running a program on your machine that connects to an external server which relays the hooks into your machine. +There are several to choose from: + +* [gh webhook](#gh-webhook) — This is a GitHub-native service, but it is currently in beta (getting access is easy, though). This is the easiest to use. +* [ngrok](#ngrok) — This is pretty easy to use, but requires setting up a free account. +* — This is another service recommended by GitHub. +* — This is another service recommended by GitHub. + +#### gh webhook + +The [`gh` CLI](https://github.com/cli/cli) is the official CLI tool which I highly recommend getting familiar with. +There is an official extension which provides webhook forwarding and also takes care of all the configuration. +See [cli/gh-webhook](https://docs.github.com/en/developers/webhooks-and-events/webhooks/receiving-webhooks-with-the-github-cli) for more information on installing it. + +This is super easy to use, and doesn't require manually configuring webhook settings. +The command to run looks something like: + +```sh +gh webhook forward --repo=ehuss/triagebot-test --events=* \ + --url=http://127.0.0.1:8000/github-hook --secret somelongsekrit +``` + +Where the value in `--secret` is the secret value you place in `GITHUB_WEBHOOK_SECRET` in the `.env` file, and `--repo` is the repo you want to test against. + +#### ngrok + +The following is an example of using to provide webhook forwarding. +You need to sign up for a free account, and also deal with configuring the GitHub webhook settings. + +1. Install ngrok. +2. Run `ngrok http 8000`. This will forward webhook events to localhost on port 8000. +3. Configure GitHub webhooks in the test repo you created. + In short: + + 1. Go to the settings page for your GitHub repo. 2. Go to the webhook section. 3. Click "Add webhook" 4. Include the settings: - - Payload URL: This is the URL to your Triagebot server, for example http://7e9ea9dc.ngrok.io/github-hook. This URL is displayed when you ran the `ngrok` command above. - - Content type: application/json - - Secret: Enter a shared secret (some longish random text) - - Events: "Send me everything" -6. Configure the `.env` file: + * Payload URL: This is the URL to your Triagebot server, for example http://7e9ea9dc.ngrok.io/github-hook. This URL is displayed when you ran the `ngrok` command above. + * Content type: application/json + * Secret: Enter a shared secret (some longish random text) + * Events: "Send me everything" - 1. Copy `.env.sample` to `.env` - 2. `GITHUB_API_TOKEN`: This is a token needed for Triagebot to send requests to GitHub. Go to GitHub Settings > Developer Settings > Personal Access Token, and create a new token. The `repo` permission should be sufficient. - If this is not set, Triagebot will also look in `~/.gitconfig` in the `github.oauth-token` setting. - 3. `DATABASE_URL`: This is the URL to the Postgres database. Something like `postgres://eric@localhost/triagebot` should work, replacing `eric` with your username. - 4. `GITHUB_WEBHOOK_SECRET`: Enter the secret you entered in the webhook above. - 5. `RUST_LOG`: Set this to `debug`. +## Tests + +When possible, writing unittests is very helpful and one of the easiest ways to test. +For more advanced testing, there is an integration test called `testsuite` which provides an end-to-end service for testing triagebot. +There are several parts to it: + +* [`github_client`](tests/github_client/mod.rs) — Tests specifically targeting `GithubClient`. + This sets up an HTTP server that mimics api.github.com and verifies the client's behavior. +* [`server_test`](tests/server_test/mod.rs) — This tests the `triagebot` server itself and its behavior when it receives a webhook. + This launches the `triagebot` server, sets up HTTP servers to intercept api.github.com requests, launches PostgreSQL in a sandbox, and then injects webhook events into the `triagebot` server and validates its response. +* [`db`](tests/db/mod.rs) — These are tests for the database API. -7. Run `cargo run --bin triagebot`. This starts the http server listening on port 8000. -8. Add a `triagebot.toml` file to the main branch of your GitHub repo with whichever services you want to try out. -9. Try interacting with your repo, such as issuing `@rustbot` commands or interacting with PRs and issues (depending on which services you enabled in `triagebot.toml`). Watch the logs from the server to see what's going on. +The real GitHub API responses are recorded in JSON files that the tests can later replay to verify the behavior of triagebot. +These recordings are enabled with the `TRIAGEBOT_TEST_RECORD` environment variable. +See the documentation in `github_client` and `server_test` for the steps for setting up recording to write a test. ## License diff --git a/src/actions.rs b/src/actions.rs index 6e7af814..f0824dd2 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -3,7 +3,6 @@ use std::collections::HashMap; use std::sync::Arc; use async_trait::async_trait; -use reqwest::Client; use serde::{Deserialize, Serialize}; use tera::{Context, Tera}; @@ -87,7 +86,7 @@ pub fn to_human(d: DateTime) -> String { #[async_trait] impl<'a> Action for Step<'a> { async fn call(&self) -> anyhow::Result { - let gh = GithubClient::new_with_default_token(Client::new()); + let gh = GithubClient::new_from_env(); // retrieve all Rust compiler meetings // from today for 7 days diff --git a/src/config.rs b/src/config.rs index 053aa682..3bfcc64e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -300,10 +300,13 @@ impl fmt::Display for ConfigurationError { Add a `triagebot.toml` in the root of the default branch to enable it." ), ConfigurationError::Toml(e) => { - write!(f, "Malformed `triagebot.toml` in default branch.\n{}", e) + write!(f, "Malformed `triagebot.toml` in default branch.\n{e}") } - ConfigurationError::Http(_) => { - write!(f, "Failed to query configuration for this repository.") + ConfigurationError::Http(e) => { + write!( + f, + "Failed to query configuration for this repository.\n{e:?}" + ) } } } diff --git a/src/db.rs b/src/db.rs index a696be99..f6a9afd7 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,276 +1,204 @@ -use crate::handlers::jobs::handle_job; -use crate::{db::jobs::*, handlers::Context}; -use anyhow::Context as _; -use chrono::Utc; -use native_tls::{Certificate, TlsConnector}; -use postgres_native_tls::MakeTlsConnector; +use self::jobs::Job; +use self::notifications::{Identifier, Notification, NotificationData}; +use anyhow::Result; +use chrono::{DateTime, FixedOffset, Utc}; +use serde::Serialize; use std::sync::{Arc, Mutex}; use tokio::sync::{OwnedSemaphorePermit, Semaphore}; -use tokio_postgres::Client as DbClient; +use uuid::Uuid; pub mod issue_data; pub mod jobs; pub mod notifications; -pub mod rustc_commits; +pub mod postgres; +pub mod sqlite; + +/// A bors merge commit. +#[derive(Debug, Serialize)] +pub struct Commit { + pub sha: String, + pub parent_sha: String, + pub time: DateTime, + pub pr: Option, +} + +#[async_trait::async_trait] +pub trait Connection: Send + Sync { + async fn transaction(&mut self) -> Box; + + // Pings + async fn record_username(&mut self, user_id: i64, username: String) -> Result<()>; + async fn record_ping(&mut self, notification: &Notification) -> Result<()>; + + // Rustc commits + async fn get_missing_commits(&mut self) -> Result>; + async fn record_commit(&mut self, commit: &Commit) -> Result<()>; + async fn has_commit(&mut self, sha: &str) -> Result; + async fn get_commits_with_artifacts(&mut self) -> Result>; + + // Notifications + async fn get_notifications(&mut self, username: &str) -> Result>; + async fn delete_ping( + &mut self, + user_id: i64, + identifier: Identifier<'_>, + ) -> Result>; + async fn add_metadata( + &mut self, + user_id: i64, + idx: usize, + metadata: Option<&str>, + ) -> Result<()>; + async fn move_indices(&mut self, user_id: i64, from: usize, to: usize) -> Result<()>; + + // Jobs + async fn insert_job( + &mut self, + name: &str, + scheduled_at: &DateTime, + metadata: &serde_json::Value, + ) -> Result<()>; + async fn delete_job(&mut self, id: &Uuid) -> Result<()>; + async fn update_job_error_message(&mut self, id: &Uuid, message: &str) -> Result<()>; + async fn update_job_executed_at(&mut self, id: &Uuid) -> Result<()>; + async fn get_job_by_name_and_scheduled_at( + &mut self, + name: &str, + scheduled_at: &DateTime, + ) -> Result; + async fn get_jobs_to_execute(&mut self) -> Result>; + + // Issue data + async fn lock_and_load_issue_data( + &mut self, + repo: &str, + issue_number: i32, + key: &str, + ) -> Result<(Box, Option)>; + async fn save_issue_data( + &mut self, + repo: &str, + issue_number: i32, + key: &str, + data: &serde_json::Value, + ) -> Result<()>; +} -const CERT_URL: &str = "https://s3.amazonaws.com/rds-downloads/rds-ca-2019-root.pem"; +#[async_trait::async_trait] +pub trait Transaction: Send + Sync { + fn conn(&mut self) -> &mut dyn Connection; + fn conn_ref(&self) -> &dyn Connection; + + async fn commit(self: Box) -> Result<(), anyhow::Error>; + async fn finish(self: Box) -> Result<(), anyhow::Error>; +} -lazy_static::lazy_static! { - static ref CERTIFICATE_PEM: Vec = { - let client = reqwest::blocking::Client::new(); - let resp = client - .get(CERT_URL) - .send() - .expect("failed to get RDS cert"); - resp.bytes().expect("failed to get RDS cert body").to_vec() - }; +#[async_trait::async_trait] +pub trait ConnectionManager { + type Connection; + async fn open(&self) -> Self::Connection; + async fn is_valid(&self, c: &mut Self::Connection) -> bool; } -pub struct ClientPool { - connections: Arc>>, +pub struct ConnectionPool { + connections: Arc>>, permits: Arc, + manager: M, } -pub struct PooledClient { - client: Option, - #[allow(unused)] // only used for drop impl +pub struct ManagedConnection { + conn: Option, + connections: Arc>>, + #[allow(unused)] permit: OwnedSemaphorePermit, - pool: Arc>>, } -impl Drop for PooledClient { - fn drop(&mut self) { - let mut clients = self.pool.lock().unwrap_or_else(|e| e.into_inner()); - clients.push(self.client.take().unwrap()); +impl std::ops::Deref for ManagedConnection { + type Target = T; + fn deref(&self) -> &Self::Target { + self.conn.as_ref().unwrap() } } - -impl std::ops::Deref for PooledClient { - type Target = tokio_postgres::Client; - - fn deref(&self) -> &Self::Target { - self.client.as_ref().unwrap() +impl std::ops::DerefMut for ManagedConnection { + fn deref_mut(&mut self) -> &mut Self::Target { + self.conn.as_mut().unwrap() } } -impl std::ops::DerefMut for PooledClient { - fn deref_mut(&mut self) -> &mut Self::Target { - self.client.as_mut().unwrap() +impl Drop for ManagedConnection { + fn drop(&mut self) { + let conn = self.conn.take().unwrap(); + self.connections + .lock() + .unwrap_or_else(|e| e.into_inner()) + .push(conn); } } -impl ClientPool { - pub fn new() -> ClientPool { - ClientPool { +impl ConnectionPool +where + T: Send, + M: ConnectionManager, +{ + fn new(manager: M) -> Self { + ConnectionPool { connections: Arc::new(Mutex::new(Vec::with_capacity(16))), permits: Arc::new(Semaphore::new(16)), + manager, } } - pub async fn get(&self) -> PooledClient { + pub fn raw(&mut self) -> &mut M { + &mut self.manager + } + + async fn get(&self) -> ManagedConnection { let permit = self.permits.clone().acquire_owned().await.unwrap(); - { + let conn = { let mut slots = self.connections.lock().unwrap_or_else(|e| e.into_inner()); - // Pop connections until we hit a non-closed connection (or there are no - // "possibly open" connections left). - while let Some(c) = slots.pop() { - if !c.is_closed() { - return PooledClient { - client: Some(c), - permit, - pool: self.connections.clone(), - }; - } + slots.pop() + }; + if let Some(mut c) = conn { + if self.manager.is_valid(&mut c).await { + return ManagedConnection { + conn: Some(c), + permit, + connections: self.connections.clone(), + }; } } - PooledClient { - client: Some(make_client().await.unwrap()), + let conn = self.manager.open().await; + ManagedConnection { + conn: Some(conn), + connections: self.connections.clone(), permit, - pool: self.connections.clone(), } } } -async fn make_client() -> anyhow::Result { - let db_url = std::env::var("DATABASE_URL").expect("needs DATABASE_URL"); - if db_url.contains("rds.amazonaws.com") { - let cert = &CERTIFICATE_PEM[..]; - let cert = Certificate::from_pem(&cert).context("made certificate")?; - let connector = TlsConnector::builder() - .add_root_certificate(cert) - .build() - .context("built TlsConnector")?; - let connector = MakeTlsConnector::new(connector); - - let (db_client, connection) = match tokio_postgres::connect(&db_url, connector).await { - Ok(v) => v, - Err(e) => { - anyhow::bail!("failed to connect to DB: {}", e); - } - }; - tokio::task::spawn(async move { - if let Err(e) = connection.await { - eprintln!("database connection error: {}", e); - } - }); - - Ok(db_client) - } else { - eprintln!("Warning: Non-TLS connection to non-RDS DB"); - let (db_client, connection) = - match tokio_postgres::connect(&db_url, tokio_postgres::NoTls).await { - Ok(v) => v, - Err(e) => { - anyhow::bail!("failed to connect to DB: {}", e); - } - }; - tokio::spawn(async move { - if let Err(e) = connection.await { - eprintln!("database connection error: {}", e); - } - }); - - Ok(db_client) - } +pub enum Pool { + Sqlite(ConnectionPool), + Postgres(ConnectionPool), } -pub async fn run_migrations(client: &DbClient) -> anyhow::Result<()> { - client - .execute( - "CREATE TABLE IF NOT EXISTS database_versions ( - zero INTEGER PRIMARY KEY, - migration_counter INTEGER - );", - &[], - ) - .await - .context("creating database versioning table")?; - - client - .execute( - "INSERT INTO database_versions (zero, migration_counter) - VALUES (0, 0) - ON CONFLICT DO NOTHING", - &[], - ) - .await - .context("inserting initial database_versions")?; - - let migration_idx: i32 = client - .query_one("SELECT migration_counter FROM database_versions", &[]) - .await - .context("getting migration counter")? - .get(0); - let migration_idx = migration_idx as usize; - - for (idx, migration) in MIGRATIONS.iter().enumerate() { - if idx >= migration_idx { - client - .execute(*migration, &[]) - .await - .with_context(|| format!("executing {}th migration", idx))?; - client - .execute( - "UPDATE database_versions SET migration_counter = $1", - &[&(idx as i32 + 1)], - ) - .await - .with_context(|| format!("updating migration counter to {}", idx))?; +impl Pool { + pub async fn connection(&self) -> Box { + match self { + Pool::Sqlite(p) => Box::new(sqlite::SqliteConnection::new(p.get().await)), + Pool::Postgres(p) => Box::new(p.get().await), } } - Ok(()) -} - -pub async fn schedule_jobs(db: &DbClient, jobs: Vec) -> anyhow::Result<()> { - for job in jobs { - let mut upcoming = job.schedule.upcoming(Utc).take(1); - - if let Some(scheduled_at) = upcoming.next() { - if let Err(_) = get_job_by_name_and_scheduled_at(&db, &job.name, &scheduled_at).await { - // mean there's no job already in the db with that name and scheduled_at - insert_job(&db, &job.name, &scheduled_at, &job.metadata).await?; - } + pub fn open(uri: &str) -> Pool { + if uri.starts_with("postgres") { + Pool::Postgres(ConnectionPool::new(postgres::Postgres::new(uri.into()))) + } else { + Pool::Sqlite(ConnectionPool::new(sqlite::Sqlite::new(uri.into()))) } } - Ok(()) -} - -pub async fn run_scheduled_jobs(ctx: &Context, db: &DbClient) -> anyhow::Result<()> { - let jobs = get_jobs_to_execute(&db).await.unwrap(); - tracing::trace!("jobs to execute: {:#?}", jobs); - - for job in jobs.iter() { - update_job_executed_at(&db, &job.id).await?; - - match handle_job(&ctx, &job.name, &job.metadata).await { - Ok(_) => { - tracing::trace!("job successfully executed (id={})", job.id); - delete_job(&db, &job.id).await?; - } - Err(e) => { - tracing::error!("job failed on execution (id={:?}, error={:?})", job.id, e); - update_job_error_message(&db, &job.id, &e.to_string()).await?; - } - } + pub fn new_from_env() -> Pool { + Self::open(&std::env::var("DATABASE_URL").expect("needs DATABASE_URL")) } - - Ok(()) } - -static MIGRATIONS: &[&str] = &[ - " -CREATE TABLE notifications ( - notification_id BIGSERIAL PRIMARY KEY, - user_id BIGINT, - origin_url TEXT NOT NULL, - origin_html TEXT, - time TIMESTAMP WITH TIME ZONE -); -", - " -CREATE TABLE users ( - user_id BIGINT PRIMARY KEY, - username TEXT NOT NULL -); -", - "ALTER TABLE notifications ADD COLUMN short_description TEXT;", - "ALTER TABLE notifications ADD COLUMN team_name TEXT;", - "ALTER TABLE notifications ADD COLUMN idx INTEGER;", - "ALTER TABLE notifications ADD COLUMN metadata TEXT;", - " -CREATE TABLE rustc_commits ( - sha TEXT PRIMARY KEY, - parent_sha TEXT NOT NULL, - time TIMESTAMP WITH TIME ZONE -); -", - "ALTER TABLE rustc_commits ADD COLUMN pr INTEGER;", - " -CREATE TABLE issue_data ( - repo TEXT, - issue_number INTEGER, - key TEXT, - data JSONB, - PRIMARY KEY (repo, issue_number, key) -); -", - " -CREATE TABLE jobs ( - id UUID DEFAULT gen_random_uuid() PRIMARY KEY, - name TEXT NOT NULL, - scheduled_at TIMESTAMP WITH TIME ZONE NOT NULL, - metadata JSONB, - executed_at TIMESTAMP WITH TIME ZONE, - error_message TEXT -); -", - " -CREATE UNIQUE INDEX jobs_name_scheduled_at_unique_index - ON jobs ( - name, scheduled_at - ); -", -]; diff --git a/src/db/issue_data.rs b/src/db/issue_data.rs index 4f2d43a0..bad50181 100644 --- a/src/db/issue_data.rs +++ b/src/db/issue_data.rs @@ -8,17 +8,15 @@ //! Note that this uses crude locking, so try to keep the duration between //! loading and saving to a minimum. -use crate::github::Issue; -use anyhow::{Context, Result}; +use crate::db; +use anyhow::Result; use serde::{Deserialize, Serialize}; -use tokio_postgres::types::Json; -use tokio_postgres::{Client as DbClient, Transaction}; pub struct IssueData<'db, T> where T: for<'a> Deserialize<'a> + Serialize + Default + std::fmt::Debug + Sync, { - transaction: Transaction<'db>, + transaction: Box, repo: String, issue_number: i32, key: String, @@ -30,27 +28,18 @@ where T: for<'a> Deserialize<'a> + Serialize + Default + std::fmt::Debug + Sync, { pub async fn load( - db: &'db mut DbClient, - issue: &Issue, + connection: &'db mut dyn db::Connection, + repo: String, + issue_number: i32, key: &str, ) -> Result> { - let repo = issue.repository().to_string(); - let issue_number = issue.number as i32; - let transaction = db.transaction().await?; - transaction - .execute("LOCK TABLE issue_data", &[]) - .await - .context("locking issue data")?; - let data = transaction - .query_opt( - "SELECT data FROM issue_data WHERE \ - repo = $1 AND issue_number = $2 AND key = $3", - &[&repo, &issue_number, &key], - ) - .await - .context("selecting issue data")? - .map(|row| row.get::>(0).0) - .unwrap_or_default(); + let (transaction, raw) = connection + .lock_and_load_issue_data(&repo, issue_number, key) + .await?; + let data = match raw { + Some(raw) => T::deserialize(raw)?, + None => T::default(), + }; Ok(IssueData { transaction, repo, @@ -60,20 +49,13 @@ where }) } - pub async fn save(self) -> Result<()> { + pub async fn save(mut self) -> Result<()> { + let raw_data = serde_json::to_value(self.data)?; self.transaction - .execute( - "INSERT INTO issue_data (repo, issue_number, key, data) \ - VALUES ($1, $2, $3, $4) \ - ON CONFLICT (repo, issue_number, key) DO UPDATE SET data=EXCLUDED.data", - &[&self.repo, &self.issue_number, &self.key, &Json(&self.data)], - ) - .await - .context("inserting issue data")?; - self.transaction - .commit() - .await - .context("committing issue data")?; + .conn() + .save_issue_data(&self.repo, self.issue_number, &self.key, &raw_data) + .await?; + self.transaction.commit().await?; Ok(()) } } diff --git a/src/db/jobs.rs b/src/db/jobs.rs index 5db66b0f..51621d3e 100644 --- a/src/db/jobs.rs +++ b/src/db/jobs.rs @@ -1,9 +1,13 @@ //! The `jobs` table provides a way to have scheduled jobs -use anyhow::{Context as _, Result}; -use chrono::{DateTime, Utc}; + +use crate::db::Connection; +use crate::handlers::jobs::handle_job; +use crate::handlers::Context; +use anyhow::Result; +use chrono::DateTime; +use chrono::Utc; use cron::Schedule; use serde::{Deserialize, Serialize}; -use tokio_postgres::Client as DbClient; use uuid::Uuid; pub struct JobSchedule { @@ -22,116 +26,46 @@ pub struct Job { pub error_message: Option, } -pub async fn insert_job( - db: &DbClient, - name: &String, - scheduled_at: &DateTime, - metadata: &serde_json::Value, -) -> Result<()> { - tracing::trace!("insert_job(name={})", name); - - db.execute( - "INSERT INTO jobs (name, scheduled_at, metadata) VALUES ($1, $2, $3) - ON CONFLICT (name, scheduled_at) DO UPDATE SET metadata = EXCLUDED.metadata", - &[&name, &scheduled_at, &metadata], - ) - .await - .context("Inserting job")?; - - Ok(()) -} - -pub async fn delete_job(db: &DbClient, id: &Uuid) -> Result<()> { - tracing::trace!("delete_job(id={})", id); - - db.execute("DELETE FROM jobs WHERE id = $1", &[&id]) - .await - .context("Deleting job")?; - - Ok(()) -} - -pub async fn update_job_error_message(db: &DbClient, id: &Uuid, message: &String) -> Result<()> { - tracing::trace!("update_job_error_message(id={})", id); - - db.execute( - "UPDATE jobs SET error_message = $2 WHERE id = $1", - &[&id, &message], - ) - .await - .context("Updating job error message")?; - - Ok(()) -} - -pub async fn update_job_executed_at(db: &DbClient, id: &Uuid) -> Result<()> { - tracing::trace!("update_job_executed_at(id={})", id); - - db.execute("UPDATE jobs SET executed_at = now() WHERE id = $1", &[&id]) - .await - .context("Updating job executed at")?; - - Ok(()) -} - -pub async fn get_job_by_name_and_scheduled_at( - db: &DbClient, - name: &String, - scheduled_at: &DateTime, -) -> Result { - tracing::trace!( - "get_job_by_name_and_scheduled_at(name={}, scheduled_at={})", - name, - scheduled_at - ); - - let job = db - .query_one( - "SELECT * FROM jobs WHERE name = $1 AND scheduled_at = $2", - &[&name, &scheduled_at], - ) - .await - .context("Select job by name and scheduled at")?; - - deserialize_job(&job) -} - -// Selects all jobs with: -// - scheduled_at in the past -// - error_message is null or executed_at is at least 60 minutes ago (intended to make repeat executions rare enough) -pub async fn get_jobs_to_execute(db: &DbClient) -> Result> { - let jobs = db - .query( - " - SELECT * FROM jobs WHERE scheduled_at <= now() AND (error_message IS NULL OR executed_at <= now() - INTERVAL '60 minutes')", - &[], - ) - .await - .context("Getting jobs data")?; - - let mut data = Vec::with_capacity(jobs.len()); +pub async fn schedule_jobs(connection: &mut dyn Connection, jobs: Vec) -> Result<()> { for job in jobs { - let serialized_job = deserialize_job(&job); - data.push(serialized_job.unwrap()); + let mut upcoming = job.schedule.upcoming(Utc).take(1); + + if let Some(scheduled_at) = upcoming.next() { + if let Err(_) = connection + .get_job_by_name_and_scheduled_at(&job.name, &scheduled_at) + .await + { + // mean there's no job already in the db with that name and scheduled_at + connection + .insert_job(&job.name, &scheduled_at, &job.metadata) + .await?; + } + } } - Ok(data) + Ok(()) } -fn deserialize_job(row: &tokio_postgres::row::Row) -> Result { - let id: Uuid = row.try_get(0)?; - let name: String = row.try_get(1)?; - let scheduled_at: DateTime = row.try_get(2)?; - let metadata: serde_json::Value = row.try_get(3)?; - let executed_at: Option> = row.try_get(4)?; - let error_message: Option = row.try_get(5)?; +pub async fn run_scheduled_jobs(ctx: &Context, connection: &mut dyn Connection) -> Result<()> { + let jobs = connection.get_jobs_to_execute().await.unwrap(); + tracing::trace!("jobs to execute: {:#?}", jobs); + + for job in jobs.iter() { + connection.update_job_executed_at(&job.id).await?; + + match handle_job(&ctx, &job.name, &job.metadata).await { + Ok(_) => { + tracing::trace!("job successfully executed (id={})", job.id); + connection.delete_job(&job.id).await?; + } + Err(e) => { + tracing::error!("job failed on execution (id={:?}, error={:?})", job.id, e); + connection + .update_job_error_message(&job.id, &e.to_string()) + .await?; + } + } + } - Ok(Job { - id, - name, - scheduled_at, - metadata, - executed_at, - error_message, - }) + Ok(()) } diff --git a/src/db/notifications.rs b/src/db/notifications.rs index 5b185793..a675f089 100644 --- a/src/db/notifications.rs +++ b/src/db/notifications.rs @@ -1,8 +1,10 @@ -use anyhow::Context as _; +//! Database support for the notifications feature for tracking `@` mentions. +//! +//! See + use chrono::{DateTime, FixedOffset}; -use tokio_postgres::Client as DbClient; -use tracing as log; +/// Tracking `@` mentions for users in issues/PRs. pub struct Notification { pub user_id: i64, pub origin_url: String, @@ -15,160 +17,7 @@ pub struct Notification { pub team_name: Option, } -pub async fn record_username(db: &DbClient, user_id: i64, username: String) -> anyhow::Result<()> { - db.execute( - "INSERT INTO users (user_id, username) VALUES ($1, $2) ON CONFLICT DO NOTHING", - &[&user_id, &username], - ) - .await - .context("inserting user id / username")?; - Ok(()) -} - -pub async fn record_ping(db: &DbClient, notification: &Notification) -> anyhow::Result<()> { - db.execute("INSERT INTO notifications (user_id, origin_url, origin_html, time, short_description, team_name, idx) - VALUES ( - $1, $2, $3, $4, $5, $6, - (SELECT max(notifications.idx) + 1 from notifications where notifications.user_id = $1) - )", - &[¬ification.user_id, ¬ification.origin_url, ¬ification.origin_html, ¬ification.time, ¬ification.short_description, ¬ification.team_name], - ).await.context("inserting notification")?; - - Ok(()) -} - -#[derive(Copy, Clone)] -pub enum Identifier<'a> { - Url(&'a str), - Index(std::num::NonZeroUsize), - /// Glob identifier (`all` or `*`). - All, -} - -pub async fn delete_ping( - db: &mut DbClient, - user_id: i64, - identifier: Identifier<'_>, -) -> anyhow::Result> { - match identifier { - Identifier::Url(origin_url) => { - let rows = db - .query( - "DELETE FROM notifications WHERE user_id = $1 and origin_url = $2 - RETURNING origin_html, time, short_description, metadata", - &[&user_id, &origin_url], - ) - .await - .context("delete notification query")?; - Ok(rows - .into_iter() - .map(|row| { - let origin_text: String = row.get(0); - let time: DateTime = row.get(1); - let short_description: Option = row.get(2); - let metadata: Option = row.get(3); - NotificationData { - origin_url: origin_url.to_owned(), - origin_text, - time, - short_description, - metadata, - } - }) - .collect()) - } - Identifier::Index(idx) => loop { - let t = db - .build_transaction() - .isolation_level(tokio_postgres::IsolationLevel::Serializable) - .start() - .await - .context("begin transaction")?; - - let notifications = t - .query( - "select notification_id, idx, user_id - from notifications - where user_id = $1 - order by idx asc nulls last;", - &[&user_id], - ) - .await - .context("failed to get ordering")?; - - let notification_id: i64 = notifications - .get(idx.get() - 1) - .ok_or_else(|| anyhow::anyhow!("No such notification with index {}", idx.get()))? - .get(0); - - let row = t - .query_one( - "DELETE FROM notifications WHERE notification_id = $1 - RETURNING origin_url, origin_html, time, short_description, metadata", - &[¬ification_id], - ) - .await - .context(format!( - "Failed to delete notification with id {}", - notification_id - ))?; - - let origin_url: String = row.get(0); - let origin_text: String = row.get(1); - let time: DateTime = row.get(2); - let short_description: Option = row.get(3); - let metadata: Option = row.get(4); - let deleted_notification = NotificationData { - origin_url, - origin_text, - time, - short_description, - metadata, - }; - - if let Err(e) = t.commit().await { - if e.code().map_or(false, |c| { - *c == tokio_postgres::error::SqlState::T_R_SERIALIZATION_FAILURE - }) { - log::trace!("serialization failure, restarting deletion"); - continue; - } else { - return Err(e).context("transaction commit failure"); - } - } else { - return Ok(vec![deleted_notification]); - } - }, - Identifier::All => { - let rows = db - .query( - "DELETE FROM notifications WHERE user_id = $1 - RETURNING origin_url, origin_html, time, short_description, metadata", - &[&user_id], - ) - .await - .context("delete all notifications query")?; - Ok(rows - .into_iter() - .map(|row| { - let origin_url: String = row.get(0); - let origin_text: String = row.get(1); - let time: DateTime = row.get(2); - let short_description: Option = row.get(3); - let metadata: Option = row.get(4); - NotificationData { - origin_url, - origin_text, - time, - short_description, - metadata, - } - }) - .collect()) - } - } -} - +/// Metadata associated with an `@` notification that the user can set via Zulip. #[derive(Debug)] pub struct NotificationData { pub origin_url: String, @@ -178,179 +27,11 @@ pub struct NotificationData { pub metadata: Option, } -pub async fn move_indices( - db: &mut DbClient, - user_id: i64, - from: usize, - to: usize, -) -> anyhow::Result<()> { - loop { - let t = db - .build_transaction() - .isolation_level(tokio_postgres::IsolationLevel::Serializable) - .start() - .await - .context("begin transaction")?; - - let notifications = t - .query( - "select notification_id, idx, user_id - from notifications - where user_id = $1 - order by idx asc nulls last;", - &[&user_id], - ) - .await - .context("failed to get initial ordering")?; - - let mut notifications = notifications - .into_iter() - .map(|n| n.get(0)) - .collect::>(); - - if notifications.get(from).is_none() { - anyhow::bail!( - "`from` index not present, must be less than {}", - notifications.len() - ); - } - - if notifications.get(to).is_none() { - anyhow::bail!( - "`to` index not present, must be less than {}", - notifications.len() - ); - } - - if from < to { - notifications[from..=to].rotate_left(1); - } else if to < from { - notifications[to..=from].rotate_right(1); - } - - for (idx, id) in notifications.into_iter().enumerate() { - t.execute( - "update notifications SET idx = $2 - where notification_id = $1", - &[&id, &(idx as i32)], - ) - .await - .context("update notification id")?; - } - - if let Err(e) = t.commit().await { - if e.code().map_or(false, |c| { - *c == tokio_postgres::error::SqlState::T_R_SERIALIZATION_FAILURE - }) { - log::trace!("serialization failure, restarting index movement"); - continue; - } else { - return Err(e).context("transaction commit failure"); - } - } else { - break; - } - } - - Ok(()) -} - -pub async fn add_metadata( - db: &mut DbClient, - user_id: i64, - idx: usize, - metadata: Option<&str>, -) -> anyhow::Result<()> { - loop { - let t = db - .build_transaction() - .isolation_level(tokio_postgres::IsolationLevel::Serializable) - .start() - .await - .context("begin transaction")?; - - let notifications = t - .query( - "select notification_id, idx, user_id - from notifications - where user_id = $1 - order by idx asc nulls last;", - &[&user_id], - ) - .await - .context("failed to get initial ordering")?; - - let notifications = notifications - .into_iter() - .map(|n| n.get(0)) - .collect::>(); - - match notifications.get(idx) { - None => anyhow::bail!( - "index not present, must be less than {}", - notifications.len() - ), - Some(id) => { - t.execute( - "update notifications SET metadata = $2 - where notification_id = $1", - &[&id, &metadata], - ) - .await - .context("update notification id")?; - } - } - - if let Err(e) = t.commit().await { - if e.code().map_or(false, |c| { - *c == tokio_postgres::error::SqlState::T_R_SERIALIZATION_FAILURE - }) { - log::trace!("serialization failure, restarting index movement"); - continue; - } else { - return Err(e).context("transaction commit failure"); - } - } else { - break; - } - } - - Ok(()) -} - -pub async fn get_notifications( - db: &DbClient, - username: &str, -) -> anyhow::Result> { - let notifications = db - .query( - " - select username, origin_url, origin_html, time, short_description, idx, metadata - from notifications - join users on notifications.user_id = users.user_id - where username = $1 - order by notifications.idx asc nulls last;", - &[&username], - ) - .await - .context("Getting notification data")?; - - let mut data = Vec::new(); - for notification in notifications { - let origin_url: String = notification.get(1); - let origin_text: String = notification.get(2); - let time: DateTime = notification.get(3); - let short_description: Option = notification.get(4); - let metadata: Option = notification.get(6); - - data.push(NotificationData { - origin_url, - origin_text, - short_description, - time, - metadata, - }); - } - - Ok(data) +/// Selector for deleting `@` notifications. +#[derive(Copy, Clone)] +pub enum Identifier<'a> { + Url(&'a str), + Index(std::num::NonZeroUsize), + /// Glob identifier (`all` or `*`). + All, } diff --git a/src/db/postgres.rs b/src/db/postgres.rs new file mode 100644 index 00000000..b9b96d8c --- /dev/null +++ b/src/db/postgres.rs @@ -0,0 +1,841 @@ +use super::{Commit, Identifier, Job, Notification, NotificationData}; +use crate::db::{Connection, ConnectionManager, ManagedConnection, Transaction}; +use anyhow::Context as _; +use anyhow::Result; +use chrono::Utc; +use chrono::{DateTime, FixedOffset}; +use native_tls::{Certificate, TlsConnector}; +use postgres_native_tls::MakeTlsConnector; +use tokio_postgres::types::Json; +use tokio_postgres::{GenericClient, TransactionBuilder}; +use tracing::trace; +use uuid::Uuid; + +pub struct Postgres(String, std::sync::Once); + +impl Postgres { + pub fn new(url: String) -> Self { + Postgres(url, std::sync::Once::new()) + } +} + +const CERT_URL: &str = "https://s3.amazonaws.com/rds-downloads/rds-ca-2019-root.pem"; + +lazy_static::lazy_static! { + static ref CERTIFICATE_PEM: Vec = { + let client = reqwest::blocking::Client::new(); + let resp = client + .get(CERT_URL) + .send() + .expect("failed to get RDS cert"); + resp.bytes().expect("failed to get RDS cert body").to_vec() + }; +} + +async fn make_client(db_url: &str) -> Result { + if db_url.contains("rds.amazonaws.com") { + let cert = &CERTIFICATE_PEM[..]; + let cert = Certificate::from_pem(&cert).context("made certificate")?; + let connector = TlsConnector::builder() + .add_root_certificate(cert) + .build() + .context("built TlsConnector")?; + let connector = MakeTlsConnector::new(connector); + + let (db_client, connection) = match tokio_postgres::connect(&db_url, connector).await { + Ok(v) => v, + Err(e) => { + anyhow::bail!("failed to connect to DB: {}", e); + } + }; + tokio::spawn(async move { + if let Err(e) = connection.await { + eprintln!("database connection error: {}", e); + } + }); + + Ok(db_client) + } else { + eprintln!("Warning: Non-TLS connection to non-RDS DB"); + let (db_client, connection) = + match tokio_postgres::connect(&db_url, tokio_postgres::NoTls).await { + Ok(v) => v, + Err(e) => { + anyhow::bail!("failed to connect to DB: {}", e); + } + }; + tokio::spawn(async move { + if let Err(e) = connection.await { + eprintln!("database connection error: {}", e); + } + }); + + Ok(db_client) + } +} + +static MIGRATIONS: &[&str] = &[ + " +CREATE TABLE notifications ( + notification_id BIGSERIAL PRIMARY KEY, + user_id BIGINT, + origin_url TEXT NOT NULL, + origin_html TEXT, + time TIMESTAMP WITH TIME ZONE +); +", + " +CREATE TABLE users ( + user_id BIGINT PRIMARY KEY, + username TEXT NOT NULL +); +", + "ALTER TABLE notifications ADD COLUMN short_description TEXT;", + "ALTER TABLE notifications ADD COLUMN team_name TEXT;", + "ALTER TABLE notifications ADD COLUMN idx INTEGER;", + "ALTER TABLE notifications ADD COLUMN metadata TEXT;", + " +CREATE TABLE rustc_commits ( + sha TEXT PRIMARY KEY, + parent_sha TEXT NOT NULL, + time TIMESTAMP WITH TIME ZONE +); +", + "ALTER TABLE rustc_commits ADD COLUMN pr INTEGER;", + " +CREATE TABLE issue_data ( + repo TEXT, + issue_number INTEGER, + key TEXT, + data JSONB, + PRIMARY KEY (repo, issue_number, key) +); +", + " +CREATE TABLE jobs ( + id UUID DEFAULT gen_random_uuid() PRIMARY KEY, + name TEXT NOT NULL, + scheduled_at TIMESTAMP WITH TIME ZONE NOT NULL, + metadata JSONB, + executed_at TIMESTAMP WITH TIME ZONE, + error_message TEXT +); +", + " +CREATE UNIQUE INDEX jobs_name_scheduled_at_unique_index + ON jobs ( + name, scheduled_at + ); +", +]; + +#[async_trait::async_trait] +impl ConnectionManager for Postgres { + type Connection = PostgresConnection; + async fn open(&self) -> Self::Connection { + let client = make_client(&self.0).await.unwrap(); + let mut should_init = false; + self.1.call_once(|| { + should_init = true; + }); + if should_init { + run_migrations(&client).await.unwrap(); + } + PostgresConnection::new(client).await + } + async fn is_valid(&self, conn: &mut Self::Connection) -> bool { + !conn.conn.is_closed() + } +} + +pub async fn run_migrations(client: &tokio_postgres::Client) -> Result<()> { + client + .execute( + "CREATE TABLE IF NOT EXISTS database_versions ( + zero INTEGER PRIMARY KEY, + migration_counter INTEGER + );", + &[], + ) + .await + .context("creating database versioning table")?; + + client + .execute( + "INSERT INTO database_versions (zero, migration_counter) + VALUES (0, 0) + ON CONFLICT DO NOTHING", + &[], + ) + .await + .context("inserting initial database_versions")?; + + let migration_idx: i32 = client + .query_one("SELECT migration_counter FROM database_versions", &[]) + .await + .context("getting migration counter")? + .get(0); + let migration_idx = migration_idx as usize; + + for (idx, migration) in MIGRATIONS.iter().enumerate() { + if idx >= migration_idx { + client + .execute(*migration, &[]) + .await + .with_context(|| format!("executing {}th migration", idx))?; + client + .execute( + "UPDATE database_versions SET migration_counter = $1", + &[&(idx as i32 + 1)], + ) + .await + .with_context(|| format!("updating migration counter to {}", idx))?; + } + } + + Ok(()) +} + +#[async_trait::async_trait] +impl<'a> Transaction for PostgresTransaction<'a> { + async fn commit(self: Box) -> Result<(), anyhow::Error> { + Ok(self.conn.commit().await?) + } + async fn finish(self: Box) -> Result<(), anyhow::Error> { + Ok(self.conn.rollback().await?) + } + fn conn(&mut self) -> &mut dyn Connection { + self + } + fn conn_ref(&self) -> &dyn Connection { + self + } +} + +pub struct PostgresTransaction<'a> { + conn: tokio_postgres::Transaction<'a>, +} + +pub struct PostgresConnection { + conn: tokio_postgres::Client, +} + +impl Into for PostgresConnection { + fn into(self) -> tokio_postgres::Client { + self.conn + } +} + +pub trait PClient { + type Client: Send + Sync + tokio_postgres::GenericClient; + fn conn(&self) -> &Self::Client; + fn conn_mut(&mut self) -> &mut Self::Client; + fn build_transaction(&mut self) -> TransactionBuilder; +} + +impl<'a> PClient for PostgresTransaction<'a> { + type Client = tokio_postgres::Transaction<'a>; + fn conn(&self) -> &Self::Client { + &self.conn + } + fn conn_mut(&mut self) -> &mut Self::Client { + &mut self.conn + } + fn build_transaction(&mut self) -> TransactionBuilder { + panic!("nested transactions not supported"); + } +} + +impl PClient for ManagedConnection { + type Client = tokio_postgres::Client; + fn conn(&self) -> &Self::Client { + &(&**self).conn + } + fn conn_mut(&mut self) -> &mut Self::Client { + &mut (&mut **self).conn + } + fn build_transaction(&mut self) -> TransactionBuilder { + self.conn_mut().build_transaction() + } +} + +impl PostgresConnection { + pub async fn new(conn: tokio_postgres::Client) -> Self { + PostgresConnection { conn } + } +} + +#[async_trait::async_trait] +impl

Connection for P +where + P: Send + Sync + PClient, +{ + async fn transaction(&mut self) -> Box { + let tx = self.conn_mut().transaction().await.unwrap(); + Box::new(PostgresTransaction { conn: tx }) + } + + async fn record_username(&mut self, user_id: i64, username: String) -> Result<()> { + self.conn() + .execute( + "INSERT INTO users (user_id, username) VALUES ($1, $2) ON CONFLICT DO NOTHING", + &[&user_id, &username], + ) + .await + .context("inserting user id / username")?; + Ok(()) + } + + async fn record_ping(&mut self, notification: &Notification) -> Result<()> { + self.conn() + .execute( + "INSERT INTO notifications + (user_id, origin_url, origin_html, time, short_description, team_name, idx) + VALUES ( + $1, $2, $3, $4, $5, $6, + (SELECT max(notifications.idx) + 1 from notifications + where notifications.user_id = $1) + )", + &[ + ¬ification.user_id, + ¬ification.origin_url, + ¬ification.origin_html, + ¬ification.time, + ¬ification.short_description, + ¬ification.team_name, + ], + ) + .await + .context("inserting notification")?; + + Ok(()) + } + + async fn get_missing_commits(&mut self) -> Result> { + let missing = self + .conn() + .query( + " + SELECT parent_sha + FROM rustc_commits + WHERE parent_sha NOT IN ( + SELECT sha + FROM rustc_commits + )", + &[], + ) + .await + .context("fetching missing commits")?; + Ok(missing.into_iter().map(|row| row.get(0)).collect()) + } + + async fn record_commit(&mut self, commit: &Commit) -> Result<()> { + trace!("record_commit(sha={})", commit.sha); + let pr = commit.pr.expect("commit has pr"); + self.conn() + .execute( + "INSERT INTO rustc_commits (sha, parent_sha, time, pr) + VALUES ($1, $2, $3, $4) ON CONFLICT DO NOTHING", + &[&commit.sha, &commit.parent_sha, &commit.time, &(pr as i32)], + ) + .await + .context("inserting commit")?; + Ok(()) + } + + async fn has_commit(&mut self, sha: &str) -> Result { + self.conn() + .query("SELECT 1 FROM rustc_commits WHERE sha = $1", &[&sha]) + .await + .context("selecting from rustc_commits") + .map(|commits| !commits.is_empty()) + } + + async fn get_commits_with_artifacts(&mut self) -> Result> { + let commits = self + .conn() + .query( + " + select sha, parent_sha, time, pr + from rustc_commits + where time >= current_date - interval '168 days' + order by time desc;", + &[], + ) + .await + .context("Getting commit data")?; + + let mut data = Vec::with_capacity(commits.len()); + for commit in commits { + let sha: String = commit.get(0); + let parent_sha: String = commit.get(1); + let time: DateTime = commit.get(2); + let pr: Option = commit.get(3); + + data.push(Commit { + sha, + parent_sha, + time, + pr: pr.map(|n| n as u32), + }); + } + + Ok(data) + } + + async fn get_notifications(&mut self, username: &str) -> Result> { + let notifications = self + .conn() + .query( + "SELECT username, origin_url, origin_html, time, short_description, idx, metadata + FROM notifications + JOIN users ON notifications.user_id = users.user_id + WHERE username = $1 + ORDER BY notifications.idx ASC NULLS LAST;", + &[&username], + ) + .await + .context("Getting notification data")?; + + let mut data = Vec::new(); + for notification in notifications { + let origin_url: String = notification.get(1); + let origin_text: String = notification.get(2); + let time: DateTime = notification.get(3); + let short_description: Option = notification.get(4); + let metadata: Option = notification.get(6); + + data.push(NotificationData { + origin_url, + origin_text, + short_description, + time, + metadata, + }); + } + + Ok(data) + } + + async fn delete_ping( + &mut self, + user_id: i64, + identifier: Identifier<'_>, + ) -> Result> { + match identifier { + Identifier::Url(origin_url) => { + let rows = self + .conn() + .query( + "DELETE FROM notifications WHERE user_id = $1 and origin_url = $2 + RETURNING origin_html, time, short_description, metadata", + &[&user_id, &origin_url], + ) + .await + .context("delete notification query")?; + Ok(rows + .into_iter() + .map(|row| { + let origin_text: String = row.get(0); + let time: DateTime = row.get(1); + let short_description: Option = row.get(2); + let metadata: Option = row.get(3); + NotificationData { + origin_url: origin_url.to_owned(), + origin_text, + time, + short_description, + metadata, + } + }) + .collect()) + } + Identifier::Index(idx) => loop { + let t = self + .build_transaction() + .isolation_level(tokio_postgres::IsolationLevel::Serializable) + .start() + .await + .context("begin transaction")?; + + let notifications = t + .query( + "SELECT notification_id, idx, user_id + FROM notifications + WHERE user_id = $1 + ORDER BY idx ASC NULLS LAST;", + &[&user_id], + ) + .await + .context("failed to get ordering")?; + + let notification_id: i64 = notifications + .get(idx.get() - 1) + .ok_or_else(|| { + anyhow::anyhow!("No such notification with index {}", idx.get()) + })? + .get(0); + + let row = t + .query_one( + "DELETE FROM notifications WHERE notification_id = $1 + RETURNING origin_url, origin_html, time, short_description, metadata", + &[¬ification_id], + ) + .await + .context(format!( + "Failed to delete notification with id {}", + notification_id + ))?; + + let origin_url: String = row.get(0); + let origin_text: String = row.get(1); + let time: DateTime = row.get(2); + let short_description: Option = row.get(3); + let metadata: Option = row.get(4); + let deleted_notification = NotificationData { + origin_url, + origin_text, + time, + short_description, + metadata, + }; + + if let Err(e) = t.commit().await { + if e.code().map_or(false, |c| { + *c == tokio_postgres::error::SqlState::T_R_SERIALIZATION_FAILURE + }) { + trace!("serialization failure, restarting deletion"); + continue; + } else { + return Err(e).context("transaction commit failure"); + } + } else { + return Ok(vec![deleted_notification]); + } + }, + Identifier::All => { + let rows = self + .conn() + .query( + "DELETE FROM notifications WHERE user_id = $1 + RETURNING origin_url, origin_html, time, short_description, metadata", + &[&user_id], + ) + .await + .context("delete all notifications query")?; + Ok(rows + .into_iter() + .map(|row| { + let origin_url: String = row.get(0); + let origin_text: String = row.get(1); + let time: DateTime = row.get(2); + let short_description: Option = row.get(3); + let metadata: Option = row.get(4); + NotificationData { + origin_url, + origin_text, + time, + short_description, + metadata, + } + }) + .collect()) + } + } + } + + async fn add_metadata( + &mut self, + user_id: i64, + idx: usize, + metadata: Option<&str>, + ) -> Result<()> { + loop { + let t = self + .build_transaction() + .isolation_level(tokio_postgres::IsolationLevel::Serializable) + .start() + .await + .context("begin transaction")?; + + let notifications = t + .query( + "SELECT notification_id, idx, user_id + FROM notifications + WHERE user_id = $1 + ORDER BY idx ASC NULLS LAST;", + &[&user_id], + ) + .await + .context("failed to get initial ordering")?; + + let notifications = notifications + .into_iter() + .map(|n| n.get(0)) + .collect::>(); + + match notifications.get(idx) { + None => anyhow::bail!( + "index not present, must be less than {}", + notifications.len() + ), + Some(id) => { + t.execute( + "UPDATE notifications SET metadata = $2 + WHERE notification_id = $1", + &[&id, &metadata], + ) + .await + .context("update notification id")?; + } + } + + if let Err(e) = t.commit().await { + if e.code().map_or(false, |c| { + *c == tokio_postgres::error::SqlState::T_R_SERIALIZATION_FAILURE + }) { + trace!("serialization failure, restarting index movement"); + continue; + } else { + return Err(e).context("transaction commit failure"); + } + } else { + break; + } + } + + Ok(()) + } + + async fn move_indices(&mut self, user_id: i64, from: usize, to: usize) -> Result<()> { + loop { + let t = self + .build_transaction() + .isolation_level(tokio_postgres::IsolationLevel::Serializable) + .start() + .await + .context("begin transaction")?; + + let notifications = t + .query( + "SELECT notification_id, idx, user_id + FROM notifications + WHERE user_id = $1 + ORDER BY idx ASC NULLS LAST;", + &[&user_id], + ) + .await + .context("failed to get initial ordering")?; + + let mut notifications = notifications + .into_iter() + .map(|n| n.get(0)) + .collect::>(); + + if notifications.get(from).is_none() { + anyhow::bail!( + "`from` index not present, must be less than {}", + notifications.len() + ); + } + + if notifications.get(to).is_none() { + anyhow::bail!( + "`to` index not present, must be less than {}", + notifications.len() + ); + } + + if from < to { + notifications[from..=to].rotate_left(1); + } else if to < from { + notifications[to..=from].rotate_right(1); + } + + for (idx, id) in notifications.into_iter().enumerate() { + t.execute( + "UPDATE notifications SET idx = $2 + WHERE notification_id = $1", + &[&id, &(idx as i32)], + ) + .await + .context("update notification id")?; + } + + if let Err(e) = t.commit().await { + if e.code().map_or(false, |c| { + *c == tokio_postgres::error::SqlState::T_R_SERIALIZATION_FAILURE + }) { + trace!("serialization failure, restarting index movement"); + continue; + } else { + return Err(e).context("transaction commit failure"); + } + } else { + break; + } + } + + Ok(()) + } + + async fn insert_job( + &mut self, + name: &str, + scheduled_at: &DateTime, + metadata: &serde_json::Value, + ) -> Result<()> { + tracing::trace!("insert_job(name={})", name); + + self.conn() + .execute( + "INSERT INTO jobs (name, scheduled_at, metadata) VALUES ($1, $2, $3) + ON CONFLICT (name, scheduled_at) DO UPDATE SET metadata = EXCLUDED.metadata", + &[&name, &scheduled_at, &metadata], + ) + .await + .context("Inserting job")?; + + Ok(()) + } + + async fn delete_job(&mut self, id: &Uuid) -> Result<()> { + tracing::trace!("delete_job(id={})", id); + + self.conn() + .execute("DELETE FROM jobs WHERE id = $1", &[id]) + .await + .context("Deleting job")?; + + Ok(()) + } + + async fn update_job_error_message(&mut self, id: &Uuid, message: &str) -> Result<()> { + tracing::trace!("update_job_error_message(id={})", id); + + self.conn() + .execute( + "UPDATE jobs SET error_message = $2 WHERE id = $1", + &[&id, &message], + ) + .await + .context("Updating job error message")?; + + Ok(()) + } + + async fn update_job_executed_at(&mut self, id: &Uuid) -> Result<()> { + tracing::trace!("update_job_executed_at(id={})", id); + + self.conn() + .execute("UPDATE jobs SET executed_at = now() WHERE id = $1", &[&id]) + .await + .context("Updating job executed at")?; + + Ok(()) + } + + async fn get_job_by_name_and_scheduled_at( + &mut self, + name: &str, + scheduled_at: &DateTime, + ) -> Result { + tracing::trace!( + "get_job_by_name_and_scheduled_at(name={}, scheduled_at={})", + name, + scheduled_at + ); + + let job = self + .conn() + .query_one( + "SELECT * FROM jobs WHERE name = $1 AND scheduled_at = $2", + &[&name, &scheduled_at], + ) + .await + .context("Select job by name and scheduled at")?; + + deserialize_job(&job) + } + + async fn get_jobs_to_execute(&mut self) -> Result> { + let jobs = self + .conn() + .query( + "SELECT * FROM jobs WHERE scheduled_at <= now() + AND (error_message IS NULL OR executed_at <= now() - INTERVAL '60 minutes')", + &[], + ) + .await + .context("Getting jobs data")?; + + let mut data = Vec::with_capacity(jobs.len()); + for job in jobs { + let serialized_job = deserialize_job(&job); + data.push(serialized_job.unwrap()); + } + + Ok(data) + } + + async fn lock_and_load_issue_data( + &mut self, + repo: &str, + issue_number: i32, + key: &str, + ) -> Result<(Box, Option)> { + let transaction = self.conn_mut().transaction().await?; + transaction + .execute("LOCK TABLE issue_data", &[]) + .await + .context("locking issue data")?; + let data = transaction + .query_opt( + "SELECT data FROM issue_data WHERE \ + repo = $1 AND issue_number = $2 AND key = $3", + &[&repo, &issue_number, &key], + ) + .await + .context("selecting issue data")? + .map(|row| row.get::>(0).0); + Ok((Box::new(PostgresTransaction { conn: transaction }), data)) + } + + async fn save_issue_data( + &mut self, + repo: &str, + issue_number: i32, + key: &str, + data: &serde_json::Value, + ) -> Result<()> { + self.conn() + .execute( + "INSERT INTO issue_data (repo, issue_number, key, data) \ + VALUES ($1, $2, $3, $4) \ + ON CONFLICT (repo, issue_number, key) DO UPDATE SET data=EXCLUDED.data", + &[&repo, &issue_number, &key, &Json(&data)], + ) + .await + .context("inserting issue data")?; + Ok(()) + } +} + +fn deserialize_job(row: &tokio_postgres::row::Row) -> Result { + let id: Uuid = row.try_get(0)?; + let name: String = row.try_get(1)?; + let scheduled_at: DateTime = row.try_get(2)?; + let metadata: serde_json::Value = row.try_get(3)?; + let executed_at: Option> = row.try_get(4)?; + let error_message: Option = row.try_get(5)?; + + Ok(Job { + id, + name, + scheduled_at, + metadata, + executed_at, + error_message, + }) +} diff --git a/src/db/rustc_commits.rs b/src/db/rustc_commits.rs deleted file mode 100644 index b272d44c..00000000 --- a/src/db/rustc_commits.rs +++ /dev/null @@ -1,79 +0,0 @@ -use anyhow::Context as _; -use chrono::{DateTime, FixedOffset}; -use tokio_postgres::Client as DbClient; - -/// A bors merge commit. -#[derive(Debug, serde::Serialize)] -pub struct Commit { - pub sha: String, - pub parent_sha: String, - pub time: DateTime, - pub pr: Option, -} - -pub async fn record_commit(db: &DbClient, commit: Commit) -> anyhow::Result<()> { - tracing::trace!("record_commit(sha={})", commit.sha); - let pr = commit.pr.expect("commit has pr"); - db.execute( - "INSERT INTO rustc_commits (sha, parent_sha, time, pr) VALUES ($1, $2, $3, $4) ON CONFLICT DO NOTHING", - &[&commit.sha, &commit.parent_sha, &commit.time, &(pr as i32)], - ) - .await - .context("inserting commit")?; - Ok(()) -} - -pub async fn has_commit(db: &DbClient, sha: &str) -> bool { - !db.query("SELECT 1 FROM rustc_commits WHERE sha = $1", &[&sha]) - .await - .unwrap() - .is_empty() -} - -pub async fn get_missing_commits(db: &DbClient) -> Vec { - let missing = db - .query( - " - SELECT parent_sha - FROM rustc_commits - WHERE parent_sha NOT IN ( - SELECT sha - FROM rustc_commits - )", - &[], - ) - .await - .unwrap(); - missing.into_iter().map(|row| row.get(0)).collect() -} - -pub async fn get_commits_with_artifacts(db: &DbClient) -> anyhow::Result> { - let commits = db - .query( - " - select sha, parent_sha, time, pr - from rustc_commits - where time >= current_date - interval '168 days' - order by time desc;", - &[], - ) - .await - .context("Getting commit data")?; - - let mut data = Vec::with_capacity(commits.len()); - for commit in commits { - let sha: String = commit.get(0); - let parent_sha: String = commit.get(1); - let time: DateTime = commit.get(2); - let pr: Option = commit.get(3); - - data.push(Commit { - sha, - parent_sha, - time, - pr: pr.map(|n| n as u32), - }); - } - - Ok(data) -} diff --git a/src/db/sqlite.rs b/src/db/sqlite.rs new file mode 100644 index 00000000..77267ac1 --- /dev/null +++ b/src/db/sqlite.rs @@ -0,0 +1,742 @@ +use super::{Commit, Identifier, Notification, NotificationData}; +use crate::db::{Connection, ConnectionManager, Job, ManagedConnection, Transaction}; +use anyhow::{Context, Result}; +use chrono::DateTime; +use chrono::Utc; +use rusqlite::params; +use std::path::PathBuf; +use std::sync::Mutex; +use std::sync::Once; +use uuid::Uuid; + +pub struct SqliteTransaction<'a> { + conn: &'a mut SqliteConnection, + finished: bool, +} + +#[async_trait::async_trait] +impl<'a> Transaction for SqliteTransaction<'a> { + async fn commit(mut self: Box) -> Result<(), anyhow::Error> { + self.finished = true; + Ok(self.conn.raw().execute_batch("COMMIT")?) + } + + async fn finish(mut self: Box) -> Result<(), anyhow::Error> { + self.finished = true; + Ok(self.conn.raw().execute_batch("ROLLBACK")?) + } + fn conn(&mut self) -> &mut dyn Connection { + &mut *self.conn + } + fn conn_ref(&self) -> &dyn Connection { + &*self.conn + } +} + +impl std::ops::Deref for SqliteTransaction<'_> { + type Target = dyn Connection; + fn deref(&self) -> &Self::Target { + &*self.conn + } +} + +impl std::ops::DerefMut for SqliteTransaction<'_> { + fn deref_mut(&mut self) -> &mut Self::Target { + self.conn + } +} + +impl Drop for SqliteTransaction<'_> { + fn drop(&mut self) { + if !self.finished { + self.conn.raw().execute_batch("ROLLBACK").unwrap(); + } + } +} + +pub struct Sqlite(PathBuf, Once); + +impl Sqlite { + pub fn new(path: PathBuf) -> Self { + if let Some(parent) = path.parent() { + if !parent.exists() { + std::fs::create_dir_all(parent).unwrap(); + } + } + Sqlite(path, Once::new()) + } +} + +struct Migration { + /// One or more SQL statements, each terminated by a semicolon. + sql: &'static str, + + /// If false, indicates that foreign key checking should be delayed until after execution of + /// the migration SQL, and foreign key `ON UPDATE` and `ON DELETE` actions disabled completely. + foreign_key_constraints_enabled: bool, +} + +impl Migration { + /// Returns a `Migration` with foreign key constraints enabled during execution. + const fn new(sql: &'static str) -> Migration { + Migration { + sql, + foreign_key_constraints_enabled: true, + } + } + + /// Returns a `Migration` with foreign key checking delayed until after execution, and foreign + /// key `ON UPDATE` and `ON DELETE` actions disabled completely. + /// + /// SQLite has limited `ALTER TABLE` capabilities, so some schema alterations require the + /// approach of replacing a table with a new one having the desired schema. Because there might + /// be other tables with foreign key constraints on the table, these constraints need to be + /// disabled during execution of such migration SQL, and reenabled after. Otherwise, dropping + /// the old table may trigger `ON DELETE` actions in the referencing tables. See [SQLite + /// documentation](https://www.sqlite.org/lang_altertable.html) for more information. + #[allow(dead_code)] + const fn without_foreign_key_constraints(sql: &'static str) -> Migration { + Migration { + sql, + foreign_key_constraints_enabled: false, + } + } + + fn execute(&self, conn: &mut rusqlite::Connection, migration_id: i32) { + if self.foreign_key_constraints_enabled { + let tx = conn.transaction().unwrap(); + tx.execute_batch(&self.sql).unwrap(); + tx.pragma_update(None, "user_version", &migration_id) + .unwrap(); + tx.commit().unwrap(); + return; + } + + // The following steps are reproduced from https://www.sqlite.org/lang_altertable.html, + // from the section titled, "Making Other Kinds Of Table Schema Changes". + + // 1. If foreign key constraints are enabled, disable them using PRAGMA foreign_keys=OFF. + conn.pragma_update(None, "foreign_keys", &"OFF").unwrap(); + + // 2. Start a transaction. + let tx = conn.transaction().unwrap(); + + // The migration SQL is responsible for steps 3 through 9. + + // 3. Remember the format of all indexes, triggers, and views associated with table X. + // This information will be needed in step 8 below. One way to do this is to run a + // query like the following: SELECT type, sql FROM sqlite_schema WHERE tbl_name='X'. + // + // 4. Use CREATE TABLE to construct a new table "new_X" that is in the desired revised + // format of table X. Make sure that the name "new_X" does not collide with any + // existing table name, of course. + // + // 5. Transfer content from X into new_X using a statement like: INSERT INTO new_X SELECT + // ... FROM X. + // + // 6. Drop the old table X: DROP TABLE X. + // + // 7. Change the name of new_X to X using: ALTER TABLE new_X RENAME TO X. + // + // 8. Use CREATE INDEX, CREATE TRIGGER, and CREATE VIEW to reconstruct indexes, triggers, + // and views associated with table X. Perhaps use the old format of the triggers, + // indexes, and views saved from step 3 above as a guide, making changes as appropriate + // for the alteration. + // + // 9. If any views refer to table X in a way that is affected by the schema change, then + // drop those views using DROP VIEW and recreate them with whatever changes are + // necessary to accommodate the schema change using CREATE VIEW. + tx.execute_batch(&self.sql).unwrap(); + + // 10. If foreign key constraints were originally enabled then run PRAGMA foreign_key_check + // to verify that the schema change did not break any foreign key constraints. + tx.pragma_query(None, "foreign_key_check", |row| { + let table: String = row.get_unwrap(0); + let row_id: Option = row.get_unwrap(1); + let foreign_table: String = row.get_unwrap(2); + let fk_idx: i64 = row.get_unwrap(3); + + tx.query_row::<(), _, _>( + "select * from pragma_foreign_key_list(?) where id = ?", + params![&table, &fk_idx], + |row| { + let col: String = row.get_unwrap(3); + let foreign_col: String = row.get_unwrap(4); + panic!( + "Foreign key violation encountered during migration\n\ + table: {},\n\ + column: {},\n\ + row_id: {:?},\n\ + foreign table: {},\n\ + foreign column: {}\n\ + migration ID: {}\n", + table, col, row_id, foreign_table, foreign_col, migration_id, + ); + }, + ) + .unwrap(); + Ok(()) + }) + .unwrap(); + + tx.pragma_update(None, "user_version", &migration_id) + .unwrap(); + + // 11. Commit the transaction started in step 2. + tx.commit().unwrap(); + + // 12. If foreign keys constraints were originally enabled, reenable them now. + conn.pragma_update(None, "foreign_keys", &"ON").unwrap(); + } +} + +static MIGRATIONS: &[Migration] = &[ + Migration::new(""), + Migration::new( + r#" +CREATE TABLE notifications ( + notification_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + user_id BIGINT, + origin_url TEXT NOT NULL, + origin_html TEXT, + time TEXT NOT NULL, + short_description TEXT, + team_name TEXT, + idx INTEGER, + metadata TEXT +); + "#, + ), + Migration::new( + r#" +CREATE TABLE users ( + user_id BIGINT PRIMARY KEY, + username TEXT NOT NULL +); + "#, + ), + Migration::new( + r#" +CREATE TABLE rustc_commits ( + sha TEXT PRIMARY KEY, + parent_sha TEXT NOT NULL, + time TEXT NOT NULL, + pr INTEGER +); + "#, + ), + Migration::new( + r#" +CREATE TABLE issue_data ( + repo TEXT, + issue_number INTEGER, + key TEXT, + data JSONB, + PRIMARY KEY (repo, issue_number, key) +); + "#, + ), + Migration::new( + r#" +CREATE TABLE jobs ( + id TEXT PRIMARY KEY, + name TEXT NOT NULL, + scheduled_at TIMESTAMP WITH TIME ZONE NOT NULL, + metadata JSONB, + executed_at TIMESTAMP WITH TIME ZONE, + error_message TEXT +); + "#, + ), + Migration::new( + r#" +CREATE UNIQUE INDEX jobs_name_scheduled_at_unique_index + ON jobs ( + name, scheduled_at + ); + "#, + ), +]; + +#[async_trait::async_trait] +impl ConnectionManager for Sqlite { + type Connection = Mutex; + async fn open(&self) -> Self::Connection { + let mut conn = rusqlite::Connection::open(&self.0).unwrap(); + conn.pragma_update(None, "cache_size", &-128000).unwrap(); + conn.pragma_update(None, "journal_mode", &"WAL").unwrap(); + conn.pragma_update(None, "foreign_keys", &"ON").unwrap(); + + self.1.call_once(|| { + let version: i32 = conn + .query_row( + "select user_version from pragma_user_version;", + params![], + |row| row.get(0), + ) + .unwrap(); + for mid in (version as usize + 1)..MIGRATIONS.len() { + MIGRATIONS[mid].execute(&mut conn, mid as i32); + } + }); + + Mutex::new(conn) + } + async fn is_valid(&self, conn: &mut Self::Connection) -> bool { + conn.get_mut() + .unwrap_or_else(|e| e.into_inner()) + .execute_batch("") + .is_ok() + } +} + +pub struct SqliteConnection { + conn: ManagedConnection>, +} + +#[async_trait::async_trait] +impl Connection for SqliteConnection { + async fn transaction(&mut self) -> Box { + Box::new(self.raw_transaction()) + } + + async fn record_username(&mut self, user_id: i64, username: String) -> Result<()> { + self.raw().execute( + "INSERT INTO users (user_id, username) VALUES (?, ?) ON CONFLICT DO NOTHING", + params![user_id, username], + )?; + Ok(()) + } + + async fn record_ping(&mut self, notification: &Notification) -> Result<()> { + self.raw().execute( + "INSERT INTO notifications + (user_id, origin_url, origin_html, time, short_description, team_name, idx) + VALUES ( + ?, ?, ?, ?, ?, ?, + (SELECT ifnull(max(notifications.idx), 0) + 1 from notifications + where notifications.user_id = ?) + )", + params![ + notification.user_id, + notification.origin_url, + notification.origin_html, + notification.time, + notification.short_description, + notification.team_name, + notification.user_id, + ], + )?; + Ok(()) + } + + async fn get_missing_commits(&mut self) -> Result> { + let commits = self + .raw() + .prepare( + " + SELECT parent_sha + FROM rustc_commits + WHERE parent_sha NOT IN ( + SELECT sha + FROM rustc_commits + )", + )? + .query_map([], |row| row.get(0))? + .collect::>()?; + Ok(commits) + } + + async fn record_commit(&mut self, commit: &Commit) -> Result<()> { + let pr = commit.pr.expect("commit has pr"); + // let time = commit.time.timestamp(); + self.raw().execute( + "INSERT INTO rustc_commits (sha, parent_sha, time, pr) \ + VALUES (?, ?, ?, ?) ON CONFLICT DO NOTHING", + params![commit.sha, commit.parent_sha, commit.time, pr], + )?; + Ok(()) + } + + async fn has_commit(&mut self, sha: &str) -> Result { + Ok(self + .raw() + .prepare("SELECT 1 FROM rustc_commits WHERE sha = ?")? + .query([sha])? + .next()? + .is_some()) + } + + async fn get_commits_with_artifacts(&mut self) -> Result> { + let commits = self + .raw() + .prepare( + "SELECT sha, parent_sha, time, pr + FROM rustc_commits + WHERE time >= datetime('now', '-168 days') + ORDER BY time DESC;", + )? + .query_map([], |row| { + let c = Commit { + sha: row.get(0)?, + parent_sha: row.get(1)?, + time: row.get(2)?, + pr: row.get(3)?, + }; + Ok(c) + })? + .collect::>()?; + Ok(commits) + } + + async fn get_notifications(&mut self, username: &str) -> Result> { + let notifications = self + .raw() + .prepare( + "SELECT username, origin_url, origin_html, time, short_description, idx, metadata + FROM notifications + JOIN users ON notifications.user_id = users.user_id + WHERE username = ? + ORDER BY notifications.idx ASC NULLS LAST;", + )? + .query_map([username], |row| { + let n = NotificationData { + origin_url: row.get(1)?, + origin_text: row.get(2)?, + time: row.get(3)?, + short_description: row.get(4)?, + metadata: row.get(6)?, + }; + Ok(n) + })? + .collect::>()?; + Ok(notifications) + } + + async fn delete_ping( + &mut self, + user_id: i64, + identifier: Identifier<'_>, + ) -> Result> { + match identifier { + Identifier::Url(origin_url) => { + let rows = self + .raw() + .prepare( + "DELETE FROM notifications WHERE user_id = ? and origin_url = ? + RETURNING origin_html, time, short_description, metadata", + )? + .query_map(params![user_id, origin_url], |row| { + let n = NotificationData { + origin_url: origin_url.to_string(), + origin_text: row.get(0)?, + time: row.get(1)?, + short_description: row.get(2)?, + metadata: row.get(3)?, + }; + Ok(n) + })? + .collect::>()?; + Ok(rows) + } + Identifier::Index(idx) => { + let deleted_notifications: Vec<_> = self + .raw() + .prepare( + "DELETE FROM notifications WHERE notification_id = ( + SELECT notification_id FROM notifications + WHERE user_id = ? + ORDER BY idx ASC NULLS LAST + LIMIT 1 OFFSET ? + ) + RETURNING origin_url, origin_html, time, short_description, metadata", + )? + .query_map(params![user_id, idx.get() - 1], |row| { + let n = NotificationData { + origin_url: row.get(0)?, + origin_text: row.get(1)?, + time: row.get(2)?, + short_description: row.get(3)?, + metadata: row.get(4)?, + }; + Ok(n) + })? + .collect::>()?; + if deleted_notifications.is_empty() { + anyhow::bail!("No such notification with index {}", idx.get()); + } + return Ok(deleted_notifications); + } + Identifier::All => { + let rows = self + .raw() + .prepare( + "DELETE FROM notifications WHERE user_id = ? + RETURNING origin_url, origin_html, time, short_description, metadata", + )? + .query_map([&user_id], |row| { + let n = NotificationData { + origin_url: row.get(0)?, + origin_text: row.get(1)?, + time: row.get(2)?, + short_description: row.get(3)?, + metadata: row.get(4)?, + }; + Ok(n) + })? + .collect::>()?; + Ok(rows) + } + } + } + + async fn add_metadata( + &mut self, + user_id: i64, + idx: usize, + metadata: Option<&str>, + ) -> Result<()> { + let t = self.raw().transaction()?; + + let notifications = t + .prepare( + "SELECT notification_id + FROM notifications + WHERE user_id = ? + ORDER BY idx ASC NULLS LAST", + )? + .query_map([user_id], |row| row.get(0)) + .context("failed to get initial ordering")? + .collect::, rusqlite::Error>>()?; + + match notifications.get(idx) { + None => anyhow::bail!( + "index not present, must be less than {}", + notifications.len() + ), + Some(id) => { + t.prepare( + "UPDATE notifications SET metadata = ? + WHERE notification_id = ?", + )? + .execute(params![metadata, id]) + .context("update notification id")?; + } + } + t.commit()?; + + Ok(()) + } + + async fn move_indices(&mut self, user_id: i64, from: usize, to: usize) -> Result<()> { + let t = self.raw().transaction()?; + + let mut notifications = t + .prepare( + "SELECT notification_id + FROM notifications + WHERE user_id = ? + ORDER BY idx ASC NULLS LAST;", + )? + .query_map([user_id], |row| row.get(0)) + .context("failed to get initial ordering")? + .collect::, rusqlite::Error>>()?; + + if notifications.get(from).is_none() { + anyhow::bail!( + "`from` index not present, must be less than {}", + notifications.len() + ); + } + + if notifications.get(to).is_none() { + anyhow::bail!( + "`to` index not present, must be less than {}", + notifications.len() + ); + } + + if from < to { + notifications[from..=to].rotate_left(1); + } else if to < from { + notifications[to..=from].rotate_right(1); + } + + for (idx, id) in notifications.into_iter().enumerate() { + t.prepare( + "UPDATE notifications SET idx = ? + WHERE notification_id = ?", + )? + .execute(params![idx, id]) + .context("update notification id")?; + } + t.commit()?; + + Ok(()) + } + + async fn insert_job( + &mut self, + name: &str, + scheduled_at: &DateTime, + metadata: &serde_json::Value, + ) -> Result<()> { + tracing::trace!("insert_job(name={})", name); + + let id = Uuid::new_v4(); + self.raw() + .execute( + "INSERT INTO jobs (id, name, scheduled_at, metadata) VALUES (?, ?, ?, ?) + ON CONFLICT (name, scheduled_at) DO UPDATE SET metadata = EXCLUDED.metadata", + params![id, name, scheduled_at, metadata], + ) + .context("Inserting job")?; + + Ok(()) + } + + async fn delete_job(&mut self, id: &Uuid) -> Result<()> { + tracing::trace!("delete_job(id={})", id); + + self.raw() + .execute("DELETE FROM jobs WHERE id = ?", [id]) + .context("Deleting job")?; + + Ok(()) + } + + async fn update_job_error_message(&mut self, id: &Uuid, message: &str) -> Result<()> { + tracing::trace!("update_job_error_message(id={})", id); + + self.raw() + .execute( + "UPDATE jobs SET error_message = ? WHERE id = ?", + params![message, id], + ) + .context("Updating job error message")?; + + Ok(()) + } + + async fn update_job_executed_at(&mut self, id: &Uuid) -> Result<()> { + tracing::trace!("update_job_executed_at(id={})", id); + + self.raw() + .execute( + "UPDATE jobs SET executed_at = datetime('now') WHERE id = ?", + [id], + ) + .context("Updating job executed at")?; + + Ok(()) + } + + async fn get_job_by_name_and_scheduled_at( + &mut self, + name: &str, + scheduled_at: &DateTime, + ) -> Result { + tracing::trace!( + "get_job_by_name_and_scheduled_at(name={}, scheduled_at={})", + name, + scheduled_at + ); + + let job = self + .raw() + .query_row( + "SELECT * FROM jobs WHERE name = ? AND scheduled_at = ?", + params![name, scheduled_at], + |row| deserialize_job(row), + ) + .context("Select job by name and scheduled at")?; + Ok(job) + } + + async fn get_jobs_to_execute(&mut self) -> Result> { + let jobs = self + .raw() + .prepare( + "SELECT * FROM jobs WHERE scheduled_at <= datetime('now') + AND (error_message IS NULL OR executed_at <= datetime('now', '-60 minutes'))", + )? + .query_map([], |row| deserialize_job(row))? + .collect::>()?; + Ok(jobs) + } + + async fn lock_and_load_issue_data( + &mut self, + repo: &str, + issue_number: i32, + key: &str, + ) -> Result<(Box, Option)> { + let transaction = self.raw_transaction(); + let data = match transaction + .conn + .raw() + .prepare( + "SELECT data FROM issue_data WHERE \ + repo = ? AND issue_number = ? AND key = ?", + )? + .query_row(params![repo, issue_number, key], |row| row.get(0)) + { + Err(rusqlite::Error::QueryReturnedNoRows) => None, + Err(e) => return Err(e.into()), + Ok(d) => Some(d), + }; + Ok((Box::new(transaction), data)) + } + + async fn save_issue_data( + &mut self, + repo: &str, + issue_number: i32, + key: &str, + data: &serde_json::Value, + ) -> Result<()> { + self.raw() + .execute( + "INSERT INTO issue_data (repo, issue_number, key, data) \ + VALUES (?, ?, ?, ?) \ + ON CONFLICT (repo, issue_number, key) DO UPDATE SET data=EXCLUDED.data", + params![repo, issue_number, key, data], + ) + .context("inserting issue data")?; + Ok(()) + } +} + +fn assert_sync() {} + +impl SqliteConnection { + pub fn new(conn: ManagedConnection>) -> Self { + assert_sync::(); + Self { conn } + } + + pub fn raw(&mut self) -> &mut rusqlite::Connection { + self.conn.get_mut().unwrap_or_else(|e| e.into_inner()) + } + pub fn raw_ref(&self) -> std::sync::MutexGuard { + self.conn.lock().unwrap_or_else(|e| e.into_inner()) + } + fn raw_transaction(&mut self) -> SqliteTransaction<'_> { + self.raw().execute_batch("BEGIN DEFERRED").unwrap(); + SqliteTransaction { + conn: self, + finished: false, + } + } +} + +fn deserialize_job(row: &rusqlite::Row<'_>) -> std::result::Result { + Ok(Job { + id: row.get(0)?, + name: row.get(1)?, + scheduled_at: row.get(2)?, + metadata: row.get(3)?, + executed_at: row.get(4)?, + error_message: row.get(5)?, + }) +} diff --git a/src/github.rs b/src/github.rs index 35309b2b..b7234e02 100644 --- a/src/github.rs +++ b/src/github.rs @@ -1,5 +1,7 @@ +use crate::test_record; use anyhow::Context; use async_trait::async_trait; +use bytes::Bytes; use chrono::{DateTime, FixedOffset, Utc}; use futures::{future::BoxFuture, FutureExt}; use hyper::header::HeaderValue; @@ -9,7 +11,7 @@ use reqwest::{Client, Request, RequestBuilder, Response, StatusCode}; use std::collections::{HashMap, HashSet}; use std::convert::TryInto; use std::{ - fmt, + fmt::{self, Write}, time::{Duration, SystemTime}, }; use tracing as log; @@ -21,22 +23,32 @@ pub struct User { } impl GithubClient { - async fn _send_req(&self, req: RequestBuilder) -> anyhow::Result<(Response, String)> { + async fn send_req(&self, req: RequestBuilder) -> anyhow::Result<(Bytes, String)> { const MAX_ATTEMPTS: usize = 2; - log::debug!("_send_req with {:?}", req); + log::debug!("send_req with {:?}", req); let req_dbg = format!("{:?}", req); let req = req .build() .with_context(|| format!("building reqwest {}", req_dbg))?; + let test_capture_info = test_record::capture_request(&req); + let mut resp = self.client.execute(req.try_clone().unwrap()).await?; if let Some(sleep) = Self::needs_retry(&resp).await { resp = self.retry(req, sleep, MAX_ATTEMPTS).await?; } + let status = resp.status(); + let maybe_err = resp.error_for_status_ref().err(); + let body = resp + .bytes() + .await + .with_context(|| format!("failed to read response body {req_dbg}"))?; + test_record::record_request(test_capture_info, status, &body); + if let Some(e) = maybe_err { + return Err(anyhow::Error::new(e)).with_context(|| format!("response: {}", String::from_utf8_lossy(&body))); + } - resp.error_for_status_ref()?; - - Ok((resp, req_dbg)) + Ok((body, req_dbg)) } async fn needs_retry(resp: &Response) -> Option { @@ -110,12 +122,13 @@ impl GithubClient { .client .execute( self.client - .get("https://api.github.com/rate_limit") + .get(&format!("{}/rate_limit", self.api_url)) .configure(self) .build() .unwrap(), ) .await?; + rate_resp.error_for_status_ref()?; let rate_limit_response = rate_resp.json::().await?; // Check url for search path because github has different rate limits for the search api @@ -151,33 +164,20 @@ impl GithubClient { .boxed() } - async fn send_req(&self, req: RequestBuilder) -> anyhow::Result> { - let (mut resp, req_dbg) = self._send_req(req).await?; - - let mut body = Vec::new(); - while let Some(chunk) = resp.chunk().await.transpose() { - let chunk = chunk - .context("reading stream failed") - .map_err(anyhow::Error::from) - .context(req_dbg.clone())?; - body.extend_from_slice(&chunk); - } - - Ok(body) - } - pub async fn json(&self, req: RequestBuilder) -> anyhow::Result where T: serde::de::DeserializeOwned, { - let (resp, req_dbg) = self._send_req(req).await?; - Ok(resp.json().await.context(req_dbg)?) + let (body, _req_dbg) = self.send_req(req).await?; + Ok(serde_json::from_slice(&body)?) } } impl User { pub async fn current(client: &GithubClient) -> anyhow::Result { - client.json(client.get("https://api.github.com/user")).await + client + .json(client.get(&format!("{}/user", client.api_url))) + .await } pub async fn is_team_member<'a>(&'a self, client: &'a GithubClient) -> anyhow::Result { @@ -252,7 +252,7 @@ pub struct Issue { pub number: u64, #[serde(deserialize_with = "opt_string")] pub body: String, - created_at: chrono::DateTime, + pub created_at: chrono::DateTime, pub updated_at: chrono::DateTime, /// The SHA for a merge commit. /// @@ -402,18 +402,18 @@ impl fmt::Display for IssueRepository { } impl IssueRepository { - fn url(&self) -> String { + fn url(&self, client: &GithubClient) -> String { format!( - "https://api.github.com/repos/{}/{}", - self.organization, self.repository + "{}/repos/{}/{}", + client.api_url, self.organization, self.repository ) } async fn has_label(&self, client: &GithubClient, label: &str) -> anyhow::Result { #[allow(clippy::redundant_pattern_matching)] - let url = format!("{}/labels/{}", self.url(), label); - match client._send_req(client.get(&url)).await { - Ok((_, _)) => Ok(true), + let url = format!("{}/labels/{}", self.url(client), label); + match client.send_req(client.get(&url)).await { + Ok(_) => Ok(true), Err(e) => { if e.downcast_ref::() .map_or(false, |e| e.status() == Some(StatusCode::NOT_FOUND)) @@ -481,19 +481,25 @@ impl Issue { } pub async fn get_comment(&self, client: &GithubClient, id: usize) -> anyhow::Result { - let comment_url = format!("{}/issues/comments/{}", self.repository().url(), id); + let comment_url = format!("{}/issues/comments/{}", self.repository().url(client), id); + let comment = client.json(client.get(&comment_url)).await?; + Ok(comment) + } + + pub async fn get_comments(&self, client: &GithubClient) -> anyhow::Result> { + let comment_url = format!("{}/issues/{}/comments", self.repository().url(client), self.number); let comment = client.json(client.get(&comment_url)).await?; Ok(comment) } pub async fn edit_body(&self, client: &GithubClient, body: &str) -> anyhow::Result<()> { - let edit_url = format!("{}/issues/{}", self.repository().url(), self.number); + let edit_url = format!("{}/issues/{}", self.repository().url(client), self.number); #[derive(serde::Serialize)] struct ChangedIssue<'a> { body: &'a str, } client - ._send_req(client.patch(&edit_url).json(&ChangedIssue { body })) + .send_req(client.patch(&edit_url).json(&ChangedIssue { body })) .await .context("failed to edit issue body")?; Ok(()) @@ -505,13 +511,13 @@ impl Issue { id: usize, new_body: &str, ) -> anyhow::Result<()> { - let comment_url = format!("{}/issues/comments/{}", self.repository().url(), id); + let comment_url = format!("{}/issues/comments/{}", self.repository().url(client), id); #[derive(serde::Serialize)] struct NewComment<'a> { body: &'a str, } client - ._send_req( + .send_req( client .patch(&comment_url) .json(&NewComment { body: new_body }), @@ -526,8 +532,13 @@ impl Issue { struct PostComment<'a> { body: &'a str, } + let comments_path = self + .comments_url + .strip_prefix("https://api.github.com") + .expect("expected api host"); + let comments_url = format!("{}{comments_path}", client.api_url); client - ._send_req(client.post(&self.comments_url).json(&PostComment { body })) + .send_req(client.post(&comments_url).json(&PostComment { body })) .await .context("failed to post comment")?; Ok(()) @@ -538,7 +549,7 @@ impl Issue { // DELETE /repos/:owner/:repo/issues/:number/labels/{name} let url = format!( "{repo_url}/issues/{number}/labels/{name}", - repo_url = self.repository().url(), + repo_url = self.repository().url(client), number = self.number, name = label, ); @@ -553,7 +564,7 @@ impl Issue { } client - ._send_req(client.delete(&url)) + .send_req(client.delete(&url)) .await .context("failed to delete label")?; @@ -570,7 +581,7 @@ impl Issue { // repo_url = https://api.github.com/repos/Codertocat/Hello-World let url = format!( "{repo_url}/issues/{number}/labels", - repo_url = self.repository().url(), + repo_url = self.repository().url(client), number = self.number ); @@ -610,7 +621,7 @@ impl Issue { } client - ._send_req(client.post(&url).json(&LabelsReq { + .send_req(client.post(&url).json(&LabelsReq { labels: known_labels, })) .await @@ -637,7 +648,7 @@ impl Issue { log::info!("remove {:?} assignees for {}", selection, self.global_id()); let url = format!( "{repo_url}/issues/{number}/assignees", - repo_url = self.repository().url(), + repo_url = self.repository().url(client), number = self.number ); @@ -661,7 +672,7 @@ impl Issue { assignees: &'a [&'a str], } client - ._send_req(client.delete(&url).json(&AssigneeReq { + .send_req(client.delete(&url).json(&AssigneeReq { assignees: &assignees[..], })) .await @@ -677,7 +688,7 @@ impl Issue { log::info!("add_assignee {} for {}", user, self.global_id()); let url = format!( "{repo_url}/issues/{number}/assignees", - repo_url = self.repository().url(), + repo_url = self.repository().url(client), number = self.number ); @@ -723,7 +734,7 @@ impl Issue { title ); - let create_url = format!("{}/milestones", self.repository().url()); + let create_url = format!("{}/milestones", self.repository().url(client)); let resp = client .send_req( client @@ -735,7 +746,7 @@ impl Issue { // fine, it just means the milestone was already created. log::trace!("Created milestone: {:?}", resp); - let list_url = format!("{}/milestones", self.repository().url()); + let list_url = format!("{}/milestones", self.repository().url(client)); let milestone_list: Vec = client.json(client.get(&list_url)).await?; let milestone_no = if let Some(milestone) = milestone_list.iter().find(|v| v.title == title) { @@ -752,9 +763,9 @@ impl Issue { struct SetMilestone { milestone: u64, } - let url = format!("{}/issues/{}", self.repository().url(), self.number); + let url = format!("{}/issues/{}", self.repository().url(client), self.number); client - ._send_req(client.patch(&url).json(&SetMilestone { + .send_req(client.patch(&url).json(&SetMilestone { milestone: milestone_no, })) .await @@ -763,13 +774,13 @@ impl Issue { } pub async fn close(&self, client: &GithubClient) -> anyhow::Result<()> { - let edit_url = format!("{}/issues/{}", self.repository().url(), self.number); + let edit_url = format!("{}/issues/{}", self.repository().url(client), self.number); #[derive(serde::Serialize)] struct CloseIssue<'a> { state: &'a str, } client - ._send_req( + .send_req( client .patch(&edit_url) .json(&CloseIssue { state: "closed" }), @@ -789,13 +800,14 @@ impl Issue { let mut req = client.get(&format!( "{}/compare/{}...{}", - self.repository().url(), + self.repository().url(client), before, after )); req = req.header("Accept", "application/vnd.github.v3.diff"); - let diff = client.send_req(req).await?; - Ok(Some(String::from(String::from_utf8_lossy(&diff)))) + let (diff, _) = client.send_req(req).await?; + let body = String::from_utf8_lossy(&diff).to_string(); + Ok(Some(body)) } /// Returns the commits from this pull request (no commits are returned if this `Issue` is not @@ -810,7 +822,7 @@ impl Issue { loop { let req = client.get(&format!( "{}/pulls/{}/commits?page={page}&per_page=100", - self.repository().url(), + self.repository().url(client), self.number )); @@ -832,7 +844,7 @@ impl Issue { let req = client.get(&format!( "{}/pulls/{}/files", - self.repository().url(), + self.repository().url(client), self.number )); Ok(client.json(req).await?) @@ -1004,11 +1016,8 @@ struct Ordering<'a> { } impl Repository { - const GITHUB_API_URL: &'static str = "https://api.github.com"; - const GITHUB_GRAPHQL_API_URL: &'static str = "https://api.github.com/graphql"; - - fn url(&self) -> String { - format!("{}/repos/{}", Repository::GITHUB_API_URL, self.full_name) + fn url(&self, client: &GithubClient) -> String { + format!("{}/repos/{}", client.api_url, self.full_name) } pub fn owner(&self) -> &str { @@ -1070,11 +1079,17 @@ impl Repository { let mut issues = vec![]; loop { let url = if use_search_api { - self.build_search_issues_url(&filters, include_labels, exclude_labels, ordering) + self.build_search_issues_url( + client, + &filters, + include_labels, + exclude_labels, + ordering, + ) } else if is_pr { - self.build_pulls_url(&filters, include_labels, ordering) + self.build_pulls_url(client, &filters, include_labels, ordering) } else { - self.build_issues_url(&filters, include_labels, ordering) + self.build_issues_url(client, &filters, include_labels, ordering) }; let result = client.get(&url); @@ -1103,24 +1118,27 @@ impl Repository { fn build_issues_url( &self, + client: &GithubClient, filters: &Vec<(&str, &str)>, include_labels: &Vec<&str>, ordering: Ordering<'_>, ) -> String { - self.build_endpoint_url("issues", filters, include_labels, ordering) + self.build_endpoint_url(client, "issues", filters, include_labels, ordering) } fn build_pulls_url( &self, + client: &GithubClient, filters: &Vec<(&str, &str)>, include_labels: &Vec<&str>, ordering: Ordering<'_>, ) -> String { - self.build_endpoint_url("pulls", filters, include_labels, ordering) + self.build_endpoint_url(client, "pulls", filters, include_labels, ordering) } fn build_endpoint_url( &self, + client: &GithubClient, endpoint: &str, filters: &Vec<(&str, &str)>, include_labels: &Vec<&str>, @@ -1143,15 +1161,13 @@ impl Repository { .join("&"); format!( "{}/repos/{}/{}?{}", - Repository::GITHUB_API_URL, - self.full_name, - endpoint, - filters + client.api_url, self.full_name, endpoint, filters ) } fn build_search_issues_url( &self, + client: &GithubClient, filters: &Vec<(&str, &str)>, include_labels: &Vec<&str>, exclude_labels: &Vec<&str>, @@ -1176,7 +1192,7 @@ impl Repository { .join("+"); format!( "{}/search/issues?q={}&sort={}&order={}&per_page={}&page={}", - Repository::GITHUB_API_URL, + client.api_url, filters, ordering.sort, ordering.direction, @@ -1187,7 +1203,7 @@ impl Repository { /// Retrieves a git commit for the given SHA. pub async fn git_commit(&self, client: &GithubClient, sha: &str) -> anyhow::Result { - let url = format!("{}/git/commits/{sha}", self.url()); + let url = format!("{}/git/commits/{sha}", self.url(client)); client .json(client.get(&url)) .await @@ -1202,7 +1218,7 @@ impl Repository { parents: &[&str], tree: &str, ) -> anyhow::Result { - let url = format!("{}/git/commits", self.url()); + let url = format!("{}/git/commits", self.url(client)); client .json(client.post(&url).json(&serde_json::json!({ "message": message, @@ -1213,29 +1229,63 @@ impl Repository { .with_context(|| format!("{} failed to create commit for tree {tree}", self.full_name)) } + /// TODO: encoding should be either "utf-8" or "base64". + pub async fn create_blob( + &self, + client: &GithubClient, + content: &str, + encoding: &str, + ) -> anyhow::Result { + let url = format!("{}/git/blobs", self.url(client)); + let resp: serde_json::Value = client + .json(client.post(&url).json(&serde_json::json!({ + "content": content, + "encoding": encoding, + }))) + .await + .with_context(|| format!("{} failed to create blob", self.full_name))?; + Ok(resp["sha"].as_str().unwrap().to_string()) + } + /// Retrieves a git reference for the given refname. pub async fn get_reference( &self, client: &GithubClient, refname: &str, ) -> anyhow::Result { - let url = format!("{}/git/ref/{}", self.url(), refname); + let url = format!("{}/git/ref/{}", self.url(client), refname); client .json(client.get(&url)) .await .with_context(|| format!("{} failed to get git reference {refname}", self.full_name)) } + pub async fn create_reference( + &self, + client: &GithubClient, + refname: &str, + sha: &str, + ) -> anyhow::Result { + let url = format!("{}/git/refs", self.url(client)); + client + .json(client.post(&url).json(&serde_json::json!({ + "ref": format!("refs/{refname}"), + "sha": sha, + }))) + .await + .with_context(|| format!("{} failed to create reference", self.full_name)) + } + /// Updates an existing git reference to a new SHA. pub async fn update_reference( &self, client: &GithubClient, refname: &str, sha: &str, - ) -> anyhow::Result<()> { - let url = format!("{}/git/refs/{}", self.url(), refname); + ) -> anyhow::Result { + let url = format!("{}/git/refs/{}", self.url(client), refname); client - ._send_req(client.patch(&url).json(&serde_json::json!({ + .json(client.patch(&url).json(&serde_json::json!({ "sha": sha, "force": true, }))) @@ -1245,8 +1295,26 @@ impl Repository { "{} failed to update reference {refname} to {sha}", self.full_name ) - })?; - Ok(()) + }) + } + + pub async fn create_or_update_reference( + &self, + client: &GithubClient, + refname: &str, + sha: &str, + ) -> anyhow::Result { + if let Err(e) = self.get_reference(client, refname).await { + if e.downcast_ref::() + .map_or(false, |e| e.status() == Some(StatusCode::NOT_FOUND)) + { + return self.create_reference(client, refname, sha).await; + } else { + return Err(e); + } + } else { + return self.update_reference(client, refname, sha).await; + } } /// Returns a list of recent commits on the given branch. @@ -1285,7 +1353,7 @@ impl Repository { let query = RecentCommits::build(args.clone()); let data = client .json::>( - client.post(Repository::GITHUB_GRAPHQL_API_URL).json(&query), + client.post(&client.graphql_url).json(&query), ) .await .with_context(|| { @@ -1424,7 +1492,7 @@ impl Repository { base_tree: &str, tree: &[GitTreeEntry], ) -> anyhow::Result { - let url = format!("{}/git/trees", self.url()); + let url = format!("{}/git/trees", self.url(client)); client .json(client.post(&url).json(&serde_json::json!({ "base_tree": base_tree, @@ -1449,7 +1517,7 @@ impl Repository { path: &str, refname: Option<&str>, ) -> anyhow::Result { - let mut url = format!("{}/contents/{}", self.url(), path); + let mut url = format!("{}/contents/{}", self.url(client), path); if let Some(refname) = refname { url.push_str("?ref="); url.push_str(refname); @@ -1471,7 +1539,7 @@ impl Repository { base: &str, body: &str, ) -> anyhow::Result { - let url = format!("{}/pulls", self.url()); + let url = format!("{}/pulls", self.url(client)); let mut issue: Issue = client .json(client.post(&url).json(&serde_json::json!({ "title": title, @@ -1490,11 +1558,48 @@ impl Repository { Ok(issue) } + pub async fn get_prs(&self, client: &GithubClient, + state: &str, + head: Option<&str>, + base: Option<&str>, + sort: Option<&str>, + direction: Option<&str>, + )-> anyhow::Result> { + let mut url = format!("{}/pulls?state={state}", self.url(client)); + if let Some(head) = head { + write!(url, "&head={head}&base={}", base.expect("base must be set if head is set")).unwrap(); + } + if let Some(sort) = sort { + write!(url, "&sort={sort}").unwrap(); + } + if let Some(direction) = direction { + write!(url, "&direction={direction}").unwrap(); + } + let mut issues: Vec = client + .json(client.get(&url)) + .await + .with_context(|| format!("{} failed to get prs", self.full_name))?; + for issue in &mut issues { + issue.pull_request = Some(PullRequestDetails {}); + } + Ok(issues) + } + + pub async fn get_pr(&self, client: &GithubClient, pull_number: u64) -> anyhow::Result { + let url = format!("{}/pulls/{pull_number}", self.url(client)); + let mut issue: Issue = client + .json(client.get(&url)) + .await + .with_context(|| format!("{} failed to get pr {pull_number}", self.full_name))?; + issue.pull_request = Some(PullRequestDetails {}); + Ok(issue) + } + /// Synchronize a branch (in a forked repository) by pulling in its upstream contents. pub async fn merge_upstream(&self, client: &GithubClient, branch: &str) -> anyhow::Result<()> { - let url = format!("{}/merge-upstream", self.url()); + let url = format!("{}/merge-upstream", self.url(client)); client - ._send_req(client.post(&url).json(&serde_json::json!({ + .send_req(client.post(&url).json(&serde_json::json!({ "branch": branch, }))) .await @@ -1506,6 +1611,42 @@ impl Repository { })?; Ok(()) } + + pub async fn has_label(&self, client: &GithubClient, label: &str) -> anyhow::Result { + // TODO merge with IssueRepository + let url = format!("{}/labels/{}", self.url(client), label); + match client.send_req(client.get(&url)).await { + Ok(_) => Ok(true), + Err(e) => { + if e.downcast_ref::() + .map_or(false, |e| e.status() == Some(StatusCode::NOT_FOUND)) + { + Ok(false) + } else { + Err(e) + } + } + } + } + + pub async fn create_label( + &self, + client: &GithubClient, + name: &str, + color: &str, + description: &str, + ) -> anyhow::Result<()> { + let url = format!("{}/labels", self.url(client)); + client + .send_req(client.post(&url).json(&serde_json::json!({ + "name": name, + "color": color, + "description": description, + }))) + .await + .with_context(|| format!("{} failed to create label {name}", self.full_name))?; + Ok(()) + } } pub struct Query<'a> { @@ -1763,15 +1904,32 @@ fn get_token_from_git_config() -> anyhow::Result { pub struct GithubClient { token: String, client: Client, + api_url: String, + graphql_url: String, + raw_url: String, } impl GithubClient { - pub fn new(client: Client, token: String) -> Self { - GithubClient { client, token } + pub fn new(token: String, api_url: String, graphql_url: String, raw_url: String) -> Self { + GithubClient { + client: Client::new(), + token, + api_url, + graphql_url, + raw_url, + } } - pub fn new_with_default_token(client: Client) -> Self { - Self::new(client, default_token_from_env()) + pub fn new_from_env() -> Self { + Self::new( + default_token_from_env(), + std::env::var("GITHUB_API_URL") + .unwrap_or_else(|_| "https://api.github.com".to_string()), + std::env::var("GITHUB_GRAPHQL_API_URL") + .unwrap_or_else(|_| "https://api.github.com/graphql".to_string()), + std::env::var("GITHUB_RAW_URL") + .unwrap_or_else(|_| "https://raw.githubusercontent.com".to_string()), + ) } pub fn raw(&self) -> &Client { @@ -1783,30 +1941,23 @@ impl GithubClient { repo: &str, branch: &str, path: &str, - ) -> anyhow::Result>> { - let url = format!( - "https://raw.githubusercontent.com/{}/{}/{}", - repo, branch, path - ); + ) -> anyhow::Result> { + let url = format!("{}/{repo}/{branch}/{path}", self.raw_url); let req = self.get(&url); let req_dbg = format!("{:?}", req); let req = req .build() .with_context(|| format!("failed to build request {:?}", req_dbg))?; - let mut resp = self.client.execute(req).await.context(req_dbg.clone())?; + let test_capture_info = test_record::capture_request(&req); + let resp = self.client.execute(req).await.context(req_dbg.clone())?; let status = resp.status(); + let body = resp + .bytes() + .await + .with_context(|| format!("failed to read response body {req_dbg}"))?; + test_record::record_request(test_capture_info, status, &body); match status { - StatusCode::OK => { - let mut buf = Vec::with_capacity(resp.content_length().unwrap_or(4) as usize); - while let Some(chunk) = resp.chunk().await.transpose() { - let chunk = chunk - .context("reading stream failed") - .map_err(anyhow::Error::from) - .context(req_dbg.clone())?; - buf.extend_from_slice(&chunk); - } - Ok(Some(buf)) - } + StatusCode::OK => Ok(Some(body)), StatusCode::NOT_FOUND => Ok(None), status => anyhow::bail!("failed to GET {}: {}", url, status), } @@ -1855,8 +2006,8 @@ impl GithubClient { pub async fn rust_commit(&self, sha: &str) -> Option { let req = self.get(&format!( - "https://api.github.com/repos/rust-lang/rust/commits/{}", - sha + "{}/repos/rust-lang/rust/commits/{sha}", + self.api_url )); match self.json(req).await { Ok(r) => Some(r), @@ -1869,7 +2020,10 @@ impl GithubClient { /// This does not retrieve all of them, only the last several. pub async fn bors_commits(&self) -> Vec { - let req = self.get("https://api.github.com/repos/rust-lang/rust/commits?author=bors"); + let req = self.get(&format!( + "{}/repos/rust-lang/rust/commits?author=bors", + self.api_url + )); match self.json(req).await { Ok(r) => r, Err(e) => { @@ -1884,9 +2038,7 @@ impl GithubClient { pub async fn is_new_contributor(&self, repo: &Repository, author: &str) -> bool { let url = format!( "{}/repos/{}/commits?author={}", - Repository::GITHUB_API_URL, - repo.full_name, - author, + self.api_url, repo.full_name, author, ); let req = self.get(&url); match self.json::>(req).await { @@ -1896,7 +2048,7 @@ impl GithubClient { Ok(res) => res.is_empty(), Err(e) => { log::warn!( - "failed to search for user commits in {} for author {author}: {e}", + "failed to search for user commits in {} for author {author}: {e:?}", repo.full_name ); false @@ -1908,7 +2060,7 @@ impl GithubClient { /// /// The `full_name` should be something like `rust-lang/rust`. pub async fn repository(&self, full_name: &str) -> anyhow::Result { - let req = self.get(&format!("{}/repos/{full_name}", Repository::GITHUB_API_URL)); + let req = self.get(&format!("{}/repos/{full_name}", self.api_url)); self.json(req) .await .with_context(|| format!("{} failed to get repo", full_name)) @@ -1953,7 +2105,13 @@ pub struct GitTreeEntry { pub mode: String, #[serde(rename = "type")] pub object_type: String, - pub sha: String, + /// `sha` and `contents` are mutually exclusive. + /// + /// Set `sha` to `Some(None)` to delete a file. + #[serde(skip_serializing_if="Option::is_none")] + pub sha: Option>, + #[serde(skip_serializing_if="Option::is_none")] + pub content: Option, } pub struct RecentCommit { @@ -2007,14 +2165,11 @@ impl IssuesQuery for LeastRecentlyReviewedPullRequests { }; loop { let query = queries::LeastRecentlyReviewedPullRequests::build(args.clone()); - let req = client.post(Repository::GITHUB_GRAPHQL_API_URL); + let req = client.post(&format!("{}/graphql", client.api_url)); let req = req.json(&query); - let (resp, req_dbg) = client._send_req(req).await?; - let data = resp - .json::>() - .await - .context(req_dbg)?; + let data: cynic::GraphQlResponse = + client.json(req).await?; if let Some(errors) = data.errors { anyhow::bail!("There were graphql errors. {:?}", errors); } diff --git a/src/handlers.rs b/src/handlers.rs index da39943b..5578b63b 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -279,7 +279,7 @@ command_handlers! { pub struct Context { pub github: GithubClient, - pub db: crate::db::ClientPool, + pub db: crate::db::Pool, pub username: String, pub octocrab: Octocrab, } diff --git a/src/handlers/docs_update.rs b/src/handlers/docs_update.rs index 1c2d0eb2..e95848b4 100644 --- a/src/handlers/docs_update.rs +++ b/src/handlers/docs_update.rs @@ -5,7 +5,6 @@ use crate::github::{self, GitTreeEntry, GithubClient, Repository}; use anyhow::Context; use anyhow::Result; use cron::Schedule; -use reqwest::Client; use std::fmt::Write; use std::str::FromStr; @@ -60,7 +59,7 @@ pub async fn handle_job() -> Result<()> { } async fn docs_update() -> Result<()> { - let gh = GithubClient::new_with_default_token(Client::new()); + let gh = GithubClient::new_from_env(); let work_repo = gh.repository(WORK_REPO).await?; work_repo .merge_upstream(&gh, &work_repo.default_branch) @@ -169,7 +168,8 @@ async fn create_commit( path: update.path.clone(), mode: "160000".to_string(), object_type: "commit".to_string(), - sha: update.new_hash.clone(), + sha: Some(Some(update.new_hash.clone())), + content: None, }) .collect(); let new_tree = rust_repo diff --git a/src/handlers/github_releases.rs b/src/handlers/github_releases.rs index 745d74fd..0df9b872 100644 --- a/src/handlers/github_releases.rs +++ b/src/handlers/github_releases.rs @@ -132,7 +132,7 @@ async fn load_changelog( .await? .ok_or_else(|| anyhow::Error::msg("missing file"))?; - Ok(String::from_utf8(resp)?) + Ok(String::from_utf8(resp.to_vec())?) } async fn load_paginated(ctx: &Context, url: &str, key: F) -> anyhow::Result> diff --git a/src/handlers/mentions.rs b/src/handlers/mentions.rs index 1c888bea..0e77b0f4 100644 --- a/src/handlers/mentions.rs +++ b/src/handlers/mentions.rs @@ -90,9 +90,11 @@ pub(super) async fn handle_input( event: &IssuesEvent, input: MentionsInput, ) -> anyhow::Result<()> { - let mut client = ctx.db.get().await; + let mut connection = ctx.db.connection().await; + let repo = event.issue.repository().to_string(); + let issue_number = event.issue.number as i32; let mut state: IssueData<'_, MentionState> = - IssueData::load(&mut client, &event.issue, MENTIONS_KEY).await?; + IssueData::load(&mut *connection, repo, issue_number, MENTIONS_KEY).await?; // Build the message to post to the issue. let mut result = String::new(); for to_mention in &input.paths { diff --git a/src/handlers/no_merges.rs b/src/handlers/no_merges.rs index b9ed89ff..14f2b41e 100644 --- a/src/handlers/no_merges.rs +++ b/src/handlers/no_merges.rs @@ -77,9 +77,11 @@ pub(super) async fn handle_input( event: &IssuesEvent, input: NoMergesInput, ) -> anyhow::Result<()> { - let mut client = ctx.db.get().await; - let mut state: IssueData<'_, NoMergesState> = - IssueData::load(&mut client, &event.issue, NO_MERGES_KEY).await?; + let mut connection = ctx.db.connection().await; + let repo = event.issue.repository().to_string(); + let issue_number = event.issue.number as i32; + let mut state: IssueData = + IssueData::load(&mut *connection, repo, issue_number, NO_MERGES_KEY).await?; let since_last_posted = if state.data.mentioned_merge_commits.is_empty() { "" diff --git a/src/handlers/notification.rs b/src/handlers/notification.rs index 718b2b24..87fbd080 100644 --- a/src/handlers/notification.rs +++ b/src/handlers/notification.rs @@ -4,8 +4,8 @@ //! //! Parsing is done in the `parser::command::ping` module. -use crate::db::notifications; use crate::{ + db::notifications::Notification, github::{self, Event}, handlers::Context, }; @@ -93,33 +93,32 @@ pub async fn handle(ctx: &Context, event: &Event) -> anyhow::Result<()> { } }; - let client = ctx.db.get().await; + let mut connection = ctx.db.connection().await; for user in users { if !users_notified.insert(user.id.unwrap()) { // Skip users already associated with this event. continue; } - if let Err(err) = notifications::record_username(&client, user.id.unwrap(), user.login) + if let Err(err) = connection + .record_username(user.id.unwrap(), user.login) .await .context("failed to record username") { log::error!("record username: {:?}", err); } - if let Err(err) = notifications::record_ping( - &client, - ¬ifications::Notification { + if let Err(err) = connection + .record_ping(&Notification { user_id: user.id.unwrap(), origin_url: event.html_url().unwrap().to_owned(), origin_html: body.to_owned(), time: event.time().unwrap(), short_description: Some(short_description.clone()), team_name: team_name.clone(), - }, - ) - .await - .context("failed to record ping") + }) + .await + .context("failed to record ping") { log::error!("record ping: {:?}", err); } diff --git a/src/handlers/rustc_commits.rs b/src/handlers/rustc_commits.rs index 4724bb2b..91c59386 100644 --- a/src/handlers/rustc_commits.rs +++ b/src/handlers/rustc_commits.rs @@ -1,6 +1,5 @@ use crate::db::jobs::JobSchedule; -use crate::db::rustc_commits; -use crate::db::rustc_commits::get_missing_commits; +use crate::db::Commit; use crate::{ github::{self, Event}, handlers::Context, @@ -87,7 +86,7 @@ async fn synchronize_commits(ctx: &Context, sha: &str, pr: u32) { } pub async fn synchronize_commits_inner(ctx: &Context, starter: Option<(String, u32)>) { - let db = ctx.db.get().await; + let mut connection = ctx.db.connection().await; // List of roots to be resolved. Each root and its parents will be recursively resolved // until an existing commit is found. @@ -96,14 +95,15 @@ pub async fn synchronize_commits_inner(ctx: &Context, starter: Option<(String, u to_be_resolved.push_back((sha.to_string(), Some(pr))); } to_be_resolved.extend( - get_missing_commits(&db) + connection + .get_missing_commits() .await + .unwrap() .into_iter() .map(|c| (c, None::)), ); log::info!("synchronize_commits for {:?}", to_be_resolved); - let db = ctx.db.get().await; while let Some((sha, mut pr)) = to_be_resolved.pop_front() { let mut gc = match ctx.github.rust_commit(&sha).await { Some(c) => c, @@ -132,19 +132,17 @@ pub async fn synchronize_commits_inner(ctx: &Context, starter: Option<(String, u } }; - let res = rustc_commits::record_commit( - &db, - rustc_commits::Commit { + let res = connection + .record_commit(&Commit { sha: gc.sha, parent_sha: parent_sha.clone(), time: gc.commit.author.date, pr: Some(pr), - }, - ) - .await; + }) + .await; match res { Ok(()) => { - if !rustc_commits::has_commit(&db, &parent_sha).await { + if !connection.has_commit(&parent_sha).await.unwrap() { to_be_resolved.push_back((parent_sha, None)) } } diff --git a/src/lib.rs b/src/lib.rs index aafa5eea..40e5da1c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,6 +26,7 @@ pub mod payload; pub mod rfcbot; pub mod team; mod team_data; +pub mod test_record; pub mod triage; pub mod zulip; diff --git a/src/main.rs b/src/main.rs index d119e3c9..8c026bc8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,6 @@ use anyhow::Context as _; use futures::future::FutureExt; use futures::StreamExt; use hyper::{header, Body, Request, Response, Server, StatusCode}; -use reqwest::Client; use route_recognizer::Router; use std::{env, net::SocketAddr, sync::Arc}; use tokio::{task, time}; @@ -83,7 +82,8 @@ async fn serve_req( .unwrap()); } if req.uri.path() == "/bors-commit-list" { - let res = db::rustc_commits::get_commits_with_artifacts(&*ctx.db.get().await).await; + let mut connection = ctx.db.connection().await; + let res = connection.get_commits_with_artifacts().await; let res = match res { Ok(r) => r, Err(e) => { @@ -103,10 +103,11 @@ async fn serve_req( if let Some(query) = req.uri.query() { let user = url::form_urlencoded::parse(query.as_bytes()).find(|(k, _)| k == "user"); if let Some((_, name)) = user { + let mut connection = ctx.db.connection().await; return Ok(Response::builder() .status(StatusCode::OK) .body(Body::from( - notification_listing::render(&ctx.db.get().await, &*name).await, + notification_listing::render(&mut *connection, &*name).await, )) .unwrap()); } @@ -219,6 +220,7 @@ async fn serve_req( .unwrap()); } }; + triagebot::test_record::record_event(&event, &payload); match triagebot::webhook(event, payload, &ctx).await { Ok(true) => Ok(Response::new(Body::from("processed request"))), @@ -234,41 +236,9 @@ async fn serve_req( } async fn run_server(addr: SocketAddr) -> anyhow::Result<()> { - let pool = db::ClientPool::new(); - db::run_migrations(&*pool.get().await) - .await - .context("database migrations")?; + let pool = db::Pool::new_from_env(); - // spawning a background task that will schedule the jobs - // every JOB_SCHEDULING_CADENCE_IN_SECS - task::spawn(async move { - loop { - let res = task::spawn(async move { - let pool = db::ClientPool::new(); - let mut interval = - time::interval(time::Duration::from_secs(JOB_SCHEDULING_CADENCE_IN_SECS)); - - loop { - interval.tick().await; - db::schedule_jobs(&*pool.get().await, jobs()) - .await - .context("database schedule jobs") - .unwrap(); - } - }); - - match res.await { - Err(err) if err.is_panic() => { - /* handle panic in above task, re-launching */ - tracing::trace!("schedule_jobs task died (error={})", err); - } - _ => unreachable!(), - } - } - }); - - let client = Client::new(); - let gh = github::GithubClient::new_with_default_token(client.clone()); + let gh = github::GithubClient::new_from_env(); let oc = octocrab::OctocrabBuilder::new() .personal_token(github::default_token_from_env()) .build() @@ -280,35 +250,10 @@ async fn run_server(addr: SocketAddr) -> anyhow::Result<()> { octocrab: oc, }); - // spawning a background task that will run the scheduled jobs - // every JOB_PROCESSING_CADENCE_IN_SECS - let ctx2 = ctx.clone(); - task::spawn(async move { - loop { - let ctx = ctx2.clone(); - let res = task::spawn(async move { - let pool = db::ClientPool::new(); - let mut interval = - time::interval(time::Duration::from_secs(JOB_PROCESSING_CADENCE_IN_SECS)); - - loop { - interval.tick().await; - db::run_scheduled_jobs(&ctx, &*pool.get().await) - .await - .context("run database scheduled jobs") - .unwrap(); - } - }); - - match res.await { - Err(err) if err.is_panic() => { - /* handle panic in above task, re-launching */ - tracing::trace!("run_scheduled_jobs task died (error={})", err); - } - _ => unreachable!(), - } - } - }); + if !is_scheduled_jobs_disabled() { + spawn_job_scheduler(); + spawn_job_runner(ctx.clone()); + } let agenda = tower::ServiceBuilder::new() .buffer(10) @@ -351,6 +296,89 @@ async fn run_server(addr: SocketAddr) -> anyhow::Result<()> { Ok(()) } +/// Spawns a background tokio task which runs continuously to queue up jobs +/// to be run by the job runner. +/// +/// The scheduler wakes up every `JOB_SCHEDULING_CADENCE_IN_SECS` seconds to +/// check if there are any jobs ready to run. Jobs get inserted into the the +/// database which acts as a queue. +fn spawn_job_scheduler() { + task::spawn(async move { + loop { + let res = task::spawn(async move { + let pool = db::Pool::new_from_env(); + let mut interval = + time::interval(time::Duration::from_secs(JOB_SCHEDULING_CADENCE_IN_SECS)); + + loop { + interval.tick().await; + let mut connection = pool.connection().await; + db::jobs::schedule_jobs(&mut *connection, jobs()) + .await + .context("database schedule jobs") + .unwrap(); + } + }); + + match res.await { + Err(err) if err.is_panic() => { + /* handle panic in above task, re-launching */ + tracing::error!("schedule_jobs task died (error={})", err); + tokio::time::sleep(std::time::Duration::new(5, 0)).await; + } + _ => unreachable!(), + } + } + }); +} + +/// Spawns a background tokio task which runs continuously to run scheduled +/// jobs. +/// +/// The runner wakes up every `JOB_PROCESSING_CADENCE_IN_SECS` seconds to +/// check if any jobs have been put into the queue by the scheduler. They +/// will get popped off the queue and run if any are found. +fn spawn_job_runner(ctx: Arc) { + task::spawn(async move { + loop { + let ctx = ctx.clone(); + let res = task::spawn(async move { + let pool = db::Pool::new_from_env(); + let mut interval = + time::interval(time::Duration::from_secs(JOB_PROCESSING_CADENCE_IN_SECS)); + + loop { + interval.tick().await; + let mut connection = pool.connection().await; + db::jobs::run_scheduled_jobs(&ctx, &mut *connection) + .await + .context("run database scheduled jobs") + .unwrap(); + } + }); + + match res.await { + Err(err) if err.is_panic() => { + /* handle panic in above task, re-launching */ + tracing::error!("run_scheduled_jobs task died (error={})", err); + tokio::time::sleep(std::time::Duration::new(5, 0)).await; + } + _ => unreachable!(), + } + } + }); +} + +/// Determines whether or not background scheduled jobs should be disabled for +/// the purpose of testing. +/// +/// This helps avoid having random jobs run while testing other things. +fn is_scheduled_jobs_disabled() -> bool { + // TRIAGEBOT_TEST_DISABLE_JOBS is set automatically by the test runner, + // and shouldn't be needed to be set manually. + env::var_os("TRIAGEBOT_TEST_DISABLE_JOBS").is_some() || triagebot::test_record::is_recording() +} + #[tokio::main(flavor = "current_thread")] async fn main() { dotenv::dotenv().ok(); @@ -359,6 +387,7 @@ async fn main() { .with_ansi(std::env::var_os("DISABLE_COLOR").is_none()) .try_init() .unwrap(); + triagebot::test_record::init().unwrap(); let port = env::var("PORT") .ok() diff --git a/src/notification_listing.rs b/src/notification_listing.rs index 033fc9b3..d827a8b2 100644 --- a/src/notification_listing.rs +++ b/src/notification_listing.rs @@ -1,7 +1,5 @@ -use crate::db::notifications::get_notifications; - -pub async fn render(db: &crate::db::PooledClient, user: &str) -> String { - let notifications = match get_notifications(db, user).await { +pub async fn render(connection: &mut dyn crate::db::Connection, user: &str) -> String { + let notifications = match connection.get_notifications(user).await { Ok(n) => n, Err(e) => { return format!("{:?}", e.context("getting notifications")); diff --git a/src/payload.rs b/src/payload.rs index f05e13a1..bd2f73f3 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -12,6 +12,13 @@ impl fmt::Display for SignedPayloadError { impl std::error::Error for SignedPayloadError {} +pub fn sign(secret: &str, payload: &[u8]) -> Vec { + let key = PKey::hmac(secret.as_bytes()).unwrap(); + let mut signer = Signer::new(MessageDigest::sha1(), &key).unwrap(); + signer.update(&payload).unwrap(); + signer.sign_to_vec().unwrap() +} + pub fn assert_signed(signature: &str, payload: &[u8]) -> Result<(), SignedPayloadError> { let signature = signature.get("sha1=".len()..).ok_or(SignedPayloadError)?; let signature = match hex::decode(&signature) { @@ -22,15 +29,8 @@ pub fn assert_signed(signature: &str, payload: &[u8]) -> Result<(), SignedPayloa } }; - let key = PKey::hmac( - std::env::var("GITHUB_WEBHOOK_SECRET") - .expect("Missing GITHUB_WEBHOOK_SECRET") - .as_bytes(), - ) - .unwrap(); - let mut signer = Signer::new(MessageDigest::sha1(), &key).unwrap(); - signer.update(&payload).unwrap(); - let hmac = signer.sign_to_vec().unwrap(); + let secret = std::env::var("GITHUB_WEBHOOK_SECRET").expect("Missing GITHUB_WEBHOOK_SECRET"); + let hmac = sign(&secret, payload); if !memcmp::eq(&hmac, &signature) { return Err(SignedPayloadError); diff --git a/src/team_data.rs b/src/team_data.rs index 4f7e1b15..d58ff408 100644 --- a/src/team_data.rs +++ b/src/team_data.rs @@ -4,7 +4,8 @@ use rust_team_data::v1::{Teams, ZulipMapping, BASE_URL}; use serde::de::DeserializeOwned; async fn by_url(client: &GithubClient, path: &str) -> anyhow::Result { - let url = format!("{}{}", BASE_URL, path); + let base = std::env::var("TEAMS_API_URL").unwrap_or(BASE_URL.to_string()); + let url = format!("{}{}", base, path); for _ in 0i32..3 { let map: Result = client.json(client.raw().get(&url)).await; match map { diff --git a/src/test_record.rs b/src/test_record.rs new file mode 100644 index 00000000..08d79a14 --- /dev/null +++ b/src/test_record.rs @@ -0,0 +1,237 @@ +//! Support for recording network activity for test playback. +//! +//! See `testsuite.rs` for more information on test recording. + +use crate::EventName; +use anyhow::Context; +use anyhow::Result; +use reqwest::{Request, StatusCode}; +use serde::{Deserialize, Serialize}; +use std::fs::{self, File}; +use std::io::BufWriter; +use std::path::Path; +use std::path::PathBuf; +use std::sync::atomic::{AtomicU32, Ordering}; +use tracing::{error, info, warn}; + +/// A representation of the recording of activity of triagebot. +/// +/// Activities are stored as JSON on disk. The test framework injects the +/// `Webhook` and then checks for the appropriate requests and sends the +/// recorded responses. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(tag = "kind")] +pub enum Activity { + /// A webhook event received from GitHub. + Webhook { + webhook_event: String, + payload: serde_json::Value, + }, + /// An outgoing request to api.github.com or raw.githubusercontent.com, and its response. + Request { + method: String, + path: String, + query: Option, + request_body: String, + response_code: u16, + /// The body of the response. + /// + /// For non-JSON requests, it is encoded as a `Value::String` under + /// the assumption that GitHub never returns a JSON string for a + /// response. This is done so that the JSON bodies can be formatted + /// nicely in the `.json` bodies to make inspecting them easier. + response_body: serde_json::Value, + }, + /// Sent by the mock HTTP server to the test framework when it detects + /// something is wrong. + Error { message: String }, + /// Sent by the mock HTTP server to the test framework to tell it that all + /// activities have been processed. + Finished, +} + +/// Information about an HTTP request that is captured before sending. +/// +/// This is needed to avoid messing with cloning the Request. +#[derive(Debug)] +pub struct RequestInfo { + method: String, + path: String, + query: Option, + body: String, +} + +/// Returns whether or not TRIAGEBOT_TEST_RECORD_DIR has been set to enable +/// recording. +pub fn is_recording() -> bool { + record_dir().is_some() +} + +/// The directory where the JSON recordings should be stored. +/// +/// Returns `None` if recording is disabled. +fn record_dir() -> Option { + let test_record = std::env::var("TRIAGEBOT_TEST_RECORD_DIR").ok()?; + let mut record_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + record_dir.push("tests"); + record_dir.push(test_record); + Some(record_dir) +} + +pub fn record_live_repo() -> Option { + std::env::var("TRIAGEBOT_TEST_LIVE_REPO").ok() +} + +fn next_sequence() -> u32 { + static NEXT_ID: AtomicU32 = AtomicU32::new(0); + NEXT_ID.fetch_add(1, Ordering::SeqCst) +} + +/// Initializes the test recording system. +/// +/// This sets up the directory where JSON files are stored if the +/// `TRIAGEBOT_TEST_RECORD_DIR` environment variable is set. +pub fn init() -> Result<()> { + let Some(record_dir) = record_dir() else { return Ok(()) }; + fs::create_dir_all(&record_dir) + .with_context(|| format!("failed to create recording directory {record_dir:?}"))?; + // Clear any old recording data. + for entry in fs::read_dir(&record_dir)? { + let entry = entry?; + let path = entry.path(); + if path.extension().and_then(|p| p.to_str()) == Some("json") { + warn!("deleting old recording at {path:?}"); + fs::remove_file(&path) + .with_context(|| format!("failed to remove old recording {path:?}"))?; + } + } + Ok(()) +} + +/// Records a webhook event for the test framework. +/// +/// The recording is only saved if the `TRIAGEBOT_TEST_RECORD_DIR` environment +/// variable is set. +pub fn record_event(event: &EventName, payload: &str) { + let Some(record_dir) = record_dir() else { return }; + + let payload_json: serde_json::Value = serde_json::from_str(payload).expect("valid json"); + let name = match event { + EventName::PullRequest => { + let action = payload_json["action"].as_str().unwrap(); + let number = payload_json["number"].as_u64().unwrap(); + format!("pr{number}_{action}") + } + EventName::PullRequestReview => { + let action = payload_json["action"].as_str().unwrap(); + let number = payload_json["pull_request"]["number"].as_u64().unwrap(); + format!("pr{number}_review_{action}") + } + EventName::PullRequestReviewComment => { + let action = payload_json["action"].as_str().unwrap(); + let number = payload_json["pull_request"]["number"].as_u64().unwrap(); + format!("pr{number}_review_comment_{action}") + } + EventName::IssueComment => { + let action = payload_json["action"].as_str().unwrap(); + let number = payload_json["issue"]["number"].as_u64().unwrap(); + format!("issue{number}_comment_{action}") + } + EventName::Issue => { + let action = payload_json["action"].as_str().unwrap(); + let number = payload_json["issue"]["number"].as_u64().unwrap(); + format!("issue{number}_{action}") + } + EventName::Push => { + let after = payload_json["after"].as_str().unwrap(); + format!("push_{after}") + } + EventName::Create => { + let ref_type = payload_json["ref_type"].as_str().unwrap(); + let git_ref = payload_json["ref"].as_str().unwrap(); + format!("create_{ref_type}_{git_ref}") + } + EventName::Other => { + return; + } + }; + let activity = Activity::Webhook { + webhook_event: event.to_string(), + payload: payload_json, + }; + let filename = format!("{:02}-webhook-{name}.json", next_sequence()); + save_activity(&record_dir.join(filename), &activity); +} + +/// Captures information about a Request to be used for a test recording. +/// +/// This value is passed to `record_request` after the request has been sent. +pub fn capture_request(req: &Request) -> Option { + if !is_recording() { + return None; + } + let url = req.url(); + let body = req + .body() + .and_then(|body| body.as_bytes()) + .map(|bytes| String::from_utf8(bytes.to_vec()).unwrap()) + .unwrap_or_default(); + let info = RequestInfo { + method: req.method().to_string(), + path: url.path().to_string(), + query: url.query().map(|q| q.to_string()), + body, + }; + Some(info) +} + +/// Records an HTTP request and response for the test framework. +/// +/// The recording is only saved if the `TRIAGEBOT_TEST_RECORD_DIR` environment +/// variable is set. +pub fn record_request(info: Option, status: StatusCode, body: &[u8]) { + let Some(info) = info else { return }; + let Some(record_dir) = record_dir() else { return }; + let response_code = status.as_u16(); + let mut munged_path = info.path.replace(['/', '.'], "_"); + if munged_path.starts_with('_') { + munged_path.remove(0); + } + let name = format!("{}-{}", info.method, munged_path); + // This is a hack to reduce the amount of data stored in the test + // directory. This file gets requested many times, and it is very + // large. + let response_body = if info.path == "/v1/teams.json" { + serde_json::json!(null) + } else { + match serde_json::from_slice(body) { + Ok(json) => json, + Err(_) => serde_json::Value::String(String::from_utf8_lossy(body).to_string()), + } + }; + let activity = Activity::Request { + method: info.method, + path: info.path, + query: info.query, + request_body: info.body, + response_code, + response_body, + }; + + let filename = format!("{:02}-{name}.json", next_sequence()); + save_activity(&record_dir.join(filename), &activity); +} + +/// Helper for saving an [`Activity`] to disk as JSON. +fn save_activity(path: &Path, activity: &Activity) { + let save_activity_inner = || -> Result<()> { + let file = File::create(path)?; + let file = BufWriter::new(file); + serde_json::to_writer_pretty(file, &activity)?; + Ok(()) + }; + if let Err(e) = save_activity_inner() { + error!("failed to save test activity {path:?}: {e:?}"); + }; + info!("test activity saved to {path:?}"); +} diff --git a/src/zulip.rs b/src/zulip.rs index 5f943982..c2ef621b 100644 --- a/src/zulip.rs +++ b/src/zulip.rs @@ -1,5 +1,4 @@ -use crate::db::notifications::add_metadata; -use crate::db::notifications::{self, delete_ping, move_indices, record_ping, Identifier}; +use crate::db::notifications::{Identifier, Notification}; use crate::github::{self, GithubClient}; use crate::handlers::Context; use anyhow::Context as _; @@ -548,8 +547,8 @@ async fn acknowledge( } else { Identifier::Url(filter) }; - let mut db = ctx.db.get().await; - match delete_ping(&mut *db, gh_id, ident).await { + let mut connection = ctx.db.connection().await; + match connection.delete_ping(gh_id, ident).await { Ok(deleted) => { let resp = if deleted.is_empty() { format!( @@ -603,18 +602,17 @@ async fn add_notification( assert_eq!(description.pop(), Some(' ')); // pop trailing space Some(description) }; - match record_ping( - &*ctx.db.get().await, - ¬ifications::Notification { + let mut connection = ctx.db.connection().await; + match connection + .record_ping(&Notification { user_id: gh_id, origin_url: url.to_owned(), origin_html: String::new(), short_description: description, time: chrono::Utc::now().into(), team_name: None, - }, - ) - .await + }) + .await { Ok(()) => Ok(serde_json::to_string(&Response { content: "Created!", @@ -652,8 +650,11 @@ async fn add_meta_notification( assert_eq!(description.pop(), Some(' ')); // pop trailing space Some(description) }; - let mut db = ctx.db.get().await; - match add_metadata(&mut db, gh_id, idx, description.as_deref()).await { + let mut connection = ctx.db.connection().await; + match connection + .add_metadata(gh_id, idx, description.as_deref()) + .await + { Ok(()) => Ok(serde_json::to_string(&Response { content: "Added metadata!", }) @@ -688,7 +689,8 @@ async fn move_notification( .context("to index")? .checked_sub(1) .ok_or_else(|| anyhow::anyhow!("1-based indexes"))?; - match move_indices(&mut *ctx.db.get().await, gh_id, from, to).await { + let mut connection = ctx.db.connection().await; + match connection.move_indices(gh_id, from, to).await { Ok(()) => Ok(serde_json::to_string(&Response { // to 1-base indices content: &format!("Moved {} to {}.", from + 1, to + 1), diff --git a/tests/db/issue_data.rs b/tests/db/issue_data.rs new file mode 100644 index 00000000..26e47099 --- /dev/null +++ b/tests/db/issue_data.rs @@ -0,0 +1,30 @@ +use super::run_test; +use serde::{Deserialize, Serialize}; +use triagebot::db::issue_data::IssueData; + +#[derive(Serialize, Deserialize, Default, Debug)] +struct MyData { + f1: String, + f2: u32, +} + +#[test] +fn issue_data() { + run_test(|mut connection| async move { + let repo = "rust-lang/rust".to_string(); + let mut id: IssueData = + IssueData::load(&mut *connection, repo.clone(), 1234, "test") + .await + .unwrap(); + assert_eq!(id.data.f1, ""); + assert_eq!(id.data.f2, 0); + id.data.f1 = "new data".to_string(); + id.data.f2 = 1; + id.save().await.unwrap(); + let id: IssueData = IssueData::load(&mut *connection, repo.clone(), 1234, "test") + .await + .unwrap(); + assert_eq!(id.data.f1, "new data"); + assert_eq!(id.data.f2, 1); + }); +} diff --git a/tests/db/jobs.rs b/tests/db/jobs.rs new file mode 100644 index 00000000..a2941063 --- /dev/null +++ b/tests/db/jobs.rs @@ -0,0 +1,113 @@ +use super::run_test; +use crate::assert_datetime_approx_equal; +use serde_json::json; + +#[test] +fn jobs() { + run_test(|mut connection| async move { + // Create some jobs and check that ones scheduled in the past are returned. + let past = chrono::Utc::now() - chrono::Duration::minutes(5); + let future = chrono::Utc::now() + chrono::Duration::hours(1); + connection + .insert_job("sample_job1", &past, &json! {{"foo": 123}}) + .await + .unwrap(); + connection + .insert_job("sample_job2", &past, &json! {{}}) + .await + .unwrap(); + connection + .insert_job("sample_job1", &future, &json! {{}}) + .await + .unwrap(); + let jobs = connection.get_jobs_to_execute().await.unwrap(); + assert_eq!(jobs.len(), 2); + assert_eq!(jobs[0].name, "sample_job1"); + assert_datetime_approx_equal(&jobs[0].scheduled_at, &past); + assert_eq!(jobs[0].metadata, json! {{"foo": 123}}); + assert_eq!(jobs[0].executed_at, None); + assert_eq!(jobs[0].error_message, None); + + assert_eq!(jobs[1].name, "sample_job2"); + assert_datetime_approx_equal(&jobs[1].scheduled_at, &past); + assert_eq!(jobs[1].metadata, json! {{}}); + assert_eq!(jobs[1].executed_at, None); + assert_eq!(jobs[1].error_message, None); + + // Get job by name + let job = connection + .get_job_by_name_and_scheduled_at("sample_job1", &future) + .await + .unwrap(); + assert_eq!(job.metadata, json! {{}}); + assert_eq!(job.error_message, None); + + // Update error message + connection + .update_job_error_message(&job.id, "an error") + .await + .unwrap(); + let job = connection + .get_job_by_name_and_scheduled_at("sample_job1", &future) + .await + .unwrap(); + assert_eq!(job.error_message.as_deref(), Some("an error")); + + // Delete job + let job = connection + .get_job_by_name_and_scheduled_at("sample_job1", &past) + .await + .unwrap(); + connection.delete_job(&job.id).await.unwrap(); + let jobs = connection.get_jobs_to_execute().await.unwrap(); + assert_eq!(jobs.len(), 1); + assert_eq!(jobs[0].name, "sample_job2"); + }); +} + +#[test] +fn on_conflict() { + // Verify that inserting a job with different data updates the data. + run_test(|mut connection| async move { + let past = chrono::Utc::now() - chrono::Duration::minutes(5); + connection + .insert_job("sample_job1", &past, &json! {{"foo": 123}}) + .await + .unwrap(); + connection + .insert_job("sample_job1", &past, &json! {{"foo": 456}}) + .await + .unwrap(); + let job = connection + .get_job_by_name_and_scheduled_at("sample_job1", &past) + .await + .unwrap(); + assert_eq!(job.metadata, json! {{"foo": 456}}); + }); +} + +#[test] +fn update_job_executed_at() { + run_test(|mut connection| async move { + let now = chrono::Utc::now(); + let past = now - chrono::Duration::minutes(5); + connection + .insert_job("sample_job1", &past, &json! {{"foo": 123}}) + .await + .unwrap(); + let jobs = connection.get_jobs_to_execute().await.unwrap(); + assert_eq!(jobs.len(), 1); + assert_eq!(jobs[0].executed_at, None); + connection + .update_job_executed_at(&jobs[0].id) + .await + .unwrap(); + let jobs = connection.get_jobs_to_execute().await.unwrap(); + assert_eq!(jobs.len(), 1); + let executed_at = jobs[0].executed_at.expect("executed_at should be set"); + // The timestamp should be approximately "now". + if executed_at - now > chrono::Duration::minutes(1) { + panic!("executed_at timestamp unexpected {executed_at:?} vs {now:?}"); + } + }); +} diff --git a/tests/db/mod.rs b/tests/db/mod.rs new file mode 100644 index 00000000..ef2dffd0 --- /dev/null +++ b/tests/db/mod.rs @@ -0,0 +1,208 @@ +//! Tests for the database API. +//! +//! These tests help verify the database interaction. The [`run_test`] +//! function helps set up the database and gives your callback a connection to +//! interact with. The general form of a test is: +//! +//! ```rust +//! #[test] +//! fn example() { +//! run_test(|mut connection| async move { +//! // Call methods on `connection` and verify its behavior. +//! }); +//! } +//! ``` +//! +//! The `run_test` function will run your test on both SQLite and Postgres (if +//! it is installed). + +use futures::Future; +use std::path::{Path, PathBuf}; +use std::process::Command; +use triagebot::db::{Connection, Pool}; + +mod issue_data; +mod jobs; +mod notification; +mod rustc_commits; + +struct PgContext { + db_dir: PathBuf, + pool: Pool, +} + +impl PgContext { + fn new(db_dir: PathBuf) -> PgContext { + let database_url = postgres_database_url(&db_dir); + let pool = Pool::open(&database_url); + PgContext { db_dir, pool } + } +} + +impl Drop for PgContext { + fn drop(&mut self) { + stop_postgres(&self.db_dir); + } +} + +struct SqliteContext { + pool: Pool, +} + +impl SqliteContext { + fn new() -> SqliteContext { + let db_path = super::test_dir().join("triagebot.sqlite3"); + let pool = Pool::open(db_path.to_str().unwrap()); + SqliteContext { pool } + } +} + +fn run_test(f: F) +where + F: Fn(Box) -> Fut + Send + Sync + 'static, + Fut: Future + Send, +{ + // Only run postgres if postgres can be found or on CI. + if let Some(db_dir) = setup_postgres() { + eprintln!("testing Postgres"); + let ctx = PgContext::new(db_dir); + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap() + .block_on(async { f(ctx.pool.connection().await).await }); + } else if std::env::var_os("CI").is_some() { + panic!("postgres must be installed in CI"); + } + + eprintln!("\n\ntesting Sqlite"); + let ctx = SqliteContext::new(); + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap() + .block_on(async { f(ctx.pool.connection().await).await }); +} + +pub fn postgres_database_url(db_dir: &PathBuf) -> String { + format!( + "postgres:///triagebot?user=triagebot&host={}", + db_dir.display() + ) +} + +pub fn setup_postgres() -> Option { + let pg_dir = find_postgres()?; + // Set up a directory where this test can store all its stuff. + let test_dir = super::test_dir(); + let db_dir = test_dir.join("db"); + + std::fs::create_dir(&db_dir).unwrap(); + let db_dir_str = db_dir.to_str().unwrap(); + run_command( + &pg_dir.join("initdb"), + &["--auth=trust", "--username=triagebot", "-D", db_dir_str], + &db_dir, + ); + run_command( + &pg_dir.join("pg_ctl"), + &[ + // -h '' tells it to not listen on TCP + // -k tells it where to place the unix-domain socket + "-o", + &format!("-h '' -k {db_dir_str}"), + // -D is the data dir where everything is stored + "-D", + db_dir_str, + // -l enables logging to a file instead of stdout + "-l", + db_dir.join("postgres.log").to_str().unwrap(), + "start", + ], + &db_dir, + ); + run_command( + &pg_dir.join("createdb"), + &["--user", "triagebot", "-h", db_dir_str, "triagebot"], + &db_dir, + ); + Some(db_dir) +} + +pub fn stop_postgres(db_dir: &Path) { + // Shut down postgres. + let pg_dir = find_postgres().unwrap(); + match Command::new(pg_dir.join("pg_ctl")) + .args(&["-D", db_dir.to_str().unwrap(), "stop"]) + .output() + { + Ok(output) => { + if !output.status.success() { + eprintln!( + "failed to stop postgres:\n\ + ---stdout\n\ + {}\n\ + ---stderr\n\ + {}\n\ + ", + std::str::from_utf8(&output.stdout).unwrap(), + std::str::from_utf8(&output.stderr).unwrap() + ); + } + } + Err(e) => eprintln!("could not run pg_ctl to stop: {e}"), + } +} + +/// Finds the root for PostgreSQL commands. +/// +/// For various reasons, some Linux distros hide some postgres commands and +/// don't put them on PATH, making them difficult to access. +fn find_postgres() -> Option { + // Check if on PATH first. + if let Ok(o) = Command::new("initdb").arg("-V").output() { + if o.status.success() { + return Some(PathBuf::new()); + } + } + if let Ok(dirs) = std::fs::read_dir("/usr/lib/postgresql") { + let mut versions: Vec<_> = dirs + .filter_map(|entry| { + let entry = entry.unwrap(); + // Versions are generally of the form 9.3 or 14, but this + // might be broken if other forms are used. + if let Ok(n) = entry.file_name().to_str().unwrap().parse::() { + Some((n, entry.path())) + } else { + None + } + }) + .collect(); + if !versions.is_empty() { + versions.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap()); + return Some(versions.last().unwrap().1.join("bin")); + } + } + None +} + +fn run_command(command: &Path, args: &[&str], cwd: &Path) { + eprintln!("running {command:?}: {args:?}"); + let output = Command::new(command) + .args(args) + .current_dir(cwd) + .output() + .unwrap_or_else(|e| panic!("`{command:?}` failed to run: {e}")); + if !output.status.success() { + panic!( + "{command:?} failed:\n\ + ---stdout\n\ + {}\n\ + ---stderr\n\ + {}\n\ + ", + std::str::from_utf8(&output.stdout).unwrap(), + std::str::from_utf8(&output.stderr).unwrap() + ); + } +} diff --git a/tests/db/notification.rs b/tests/db/notification.rs new file mode 100644 index 00000000..8edd986b --- /dev/null +++ b/tests/db/notification.rs @@ -0,0 +1,261 @@ +use super::run_test; +use crate::assert_datetime_approx_equal; +use std::num::NonZeroUsize; +use triagebot::db::notifications::{Identifier, Notification}; + +#[test] +fn notification() { + run_test(|mut connection| async move { + let now = chrono::Utc::now(); + connection + .record_username(43198, "ehuss".to_string()) + .await + .unwrap(); + connection + .record_username(14314532, "weihanglo".to_string()) + .await + .unwrap(); + connection + .record_ping(&Notification { + user_id: 43198, + origin_url: "https://github.com/rust-lang/rust/issues/1".to_string(), + origin_html: "This comment mentions @ehuss.".to_string(), + short_description: Some("Comment on some issue".to_string()), + time: now.into(), + team_name: None, + }) + .await + .unwrap(); + + connection + .record_ping(&Notification { + user_id: 43198, + origin_url: "https://github.com/rust-lang/rust/issues/2".to_string(), + origin_html: "This comment mentions @rust-lang/cargo.".to_string(), + short_description: Some("Comment on some issue".to_string()), + time: now.into(), + team_name: Some("cargo".to_string()), + }) + .await + .unwrap(); + connection + .record_ping(&Notification { + user_id: 14314532, + origin_url: "https://github.com/rust-lang/rust/issues/2".to_string(), + origin_html: "This comment mentions @rust-lang/cargo.".to_string(), + short_description: Some("Comment on some issue".to_string()), + time: now.into(), + team_name: Some("cargo".to_string()), + }) + .await + .unwrap(); + + let notifications = connection.get_notifications("ehuss").await.unwrap(); + assert_eq!(notifications.len(), 2); + assert_eq!( + notifications[0].origin_url, + "https://github.com/rust-lang/rust/issues/1" + ); + assert_eq!( + notifications[0].origin_text, + "This comment mentions @ehuss." + ); + assert_eq!( + notifications[0].short_description.as_deref(), + Some("Comment on some issue") + ); + assert_datetime_approx_equal(¬ifications[0].time, &now); + assert_eq!(notifications[0].metadata, None); + + assert_eq!( + notifications[1].origin_url, + "https://github.com/rust-lang/rust/issues/2" + ); + assert_eq!( + notifications[1].origin_text, + "This comment mentions @rust-lang/cargo." + ); + assert_eq!( + notifications[1].short_description.as_deref(), + Some("Comment on some issue") + ); + assert_datetime_approx_equal(¬ifications[1].time, &now); + assert_eq!(notifications[1].metadata, None); + + let notifications = connection.get_notifications("weihanglo").await.unwrap(); + assert_eq!(notifications.len(), 1); + assert_eq!( + notifications[0].origin_url, + "https://github.com/rust-lang/rust/issues/2" + ); + assert_eq!( + notifications[0].origin_text, + "This comment mentions @rust-lang/cargo." + ); + assert_eq!( + notifications[0].short_description.as_deref(), + Some("Comment on some issue") + ); + assert_datetime_approx_equal(¬ifications[0].time, &now); + assert_eq!(notifications[0].metadata, None); + + let notifications = connection.get_notifications("octocat").await.unwrap(); + assert_eq!(notifications.len(), 0); + }); +} + +#[test] +fn delete_ping() { + run_test(|mut connection| async move { + connection + .record_username(43198, "ehuss".to_string()) + .await + .unwrap(); + let now = chrono::Utc::now(); + for x in 1..4 { + connection + .record_ping(&Notification { + user_id: 43198, + origin_url: x.to_string(), + origin_html: "@ehuss {n}".to_string(), + short_description: Some("Comment on some issue".to_string()), + time: now.into(), + team_name: None, + }) + .await + .unwrap(); + } + + let notifications = connection.get_notifications("ehuss").await.unwrap(); + assert_eq!(notifications.len(), 3); + assert_eq!(notifications[0].origin_url, "1"); + assert_eq!(notifications[1].origin_url, "2"); + assert_eq!(notifications[2].origin_url, "3"); + + match connection + .delete_ping(43198, Identifier::Index(NonZeroUsize::new(5).unwrap())) + .await + { + Err(e) => assert_eq!(e.to_string(), "No such notification with index 5"), + Ok(deleted) => panic!("did not expect success {deleted:?}"), + } + + let deleted = connection + .delete_ping(43198, Identifier::Index(NonZeroUsize::new(2).unwrap())) + .await + .unwrap(); + assert_eq!(deleted.len(), 1); + assert_eq!(deleted[0].origin_url, "2"); + let notifications = connection.get_notifications("ehuss").await.unwrap(); + assert_eq!(notifications.len(), 2); + assert_eq!(notifications[0].origin_url, "1"); + assert_eq!(notifications[1].origin_url, "3"); + + let deleted = connection + .delete_ping(43198, Identifier::Url("1")) + .await + .unwrap(); + assert_eq!(deleted.len(), 1); + assert_eq!(deleted[0].origin_url, "1"); + let notifications = connection.get_notifications("ehuss").await.unwrap(); + assert_eq!(notifications.len(), 1); + assert_eq!(notifications[0].origin_url, "3"); + + for x in 4..6 { + connection + .record_ping(&Notification { + user_id: 43198, + origin_url: x.to_string(), + origin_html: "@ehuss {n}".to_string(), + short_description: Some("Comment on some issue".to_string()), + time: now.into(), + team_name: None, + }) + .await + .unwrap(); + } + + let notifications = connection.get_notifications("ehuss").await.unwrap(); + assert_eq!(notifications.len(), 3); + assert_eq!(notifications[0].origin_url, "3"); + assert_eq!(notifications[1].origin_url, "4"); + assert_eq!(notifications[2].origin_url, "5"); + + let deleted = connection + .delete_ping(43198, Identifier::Index(NonZeroUsize::new(2).unwrap())) + .await + .unwrap(); + assert_eq!(deleted.len(), 1); + assert_eq!(deleted[0].origin_url, "4"); + + let deleted = connection + .delete_ping(43198, Identifier::All) + .await + .unwrap(); + assert_eq!(deleted.len(), 2); + assert_eq!(deleted[0].origin_url, "3"); + assert_eq!(deleted[1].origin_url, "5"); + + let notifications = connection.get_notifications("ehuss").await.unwrap(); + assert_eq!(notifications.len(), 0); + }); +} + +#[test] +fn meta_notification() { + run_test(|mut connection| async move { + let now = chrono::Utc::now(); + connection + .record_username(43198, "ehuss".to_string()) + .await + .unwrap(); + connection + .record_ping(&Notification { + user_id: 43198, + origin_url: "1".to_string(), + origin_html: "This comment mentions @ehuss.".to_string(), + short_description: Some("Comment on some issue".to_string()), + time: now.into(), + team_name: None, + }) + .await + .unwrap(); + connection + .add_metadata(43198, 0, Some("metadata 1")) + .await + .unwrap(); + let notifications = connection.get_notifications("ehuss").await.unwrap(); + assert_eq!(notifications.len(), 1); + assert_eq!(notifications[0].metadata.as_deref(), Some("metadata 1")); + }); +} + +#[test] +fn move_indices() { + run_test(|mut connection| async move { + let now = chrono::Utc::now(); + connection + .record_username(43198, "ehuss".to_string()) + .await + .unwrap(); + for x in 1..4 { + connection + .record_ping(&Notification { + user_id: 43198, + origin_url: x.to_string(), + origin_html: "@ehuss {n}".to_string(), + short_description: Some("Comment on some issue".to_string()), + time: now.into(), + team_name: None, + }) + .await + .unwrap(); + } + connection.move_indices(43198, 1, 0).await.unwrap(); + let notifications = connection.get_notifications("ehuss").await.unwrap(); + assert_eq!(notifications.len(), 3); + assert_eq!(notifications[0].origin_url, "2"); + assert_eq!(notifications[1].origin_url, "1"); + assert_eq!(notifications[2].origin_url, "3"); + }); +} diff --git a/tests/db/rustc_commits.rs b/tests/db/rustc_commits.rs new file mode 100644 index 00000000..8c36c6fb --- /dev/null +++ b/tests/db/rustc_commits.rs @@ -0,0 +1,87 @@ +use super::run_test; +use crate::assert_datetime_approx_equal; +use triagebot::db::Commit; + +#[test] +fn rustc_commits() { + run_test(|mut connection| async move { + // Using current time since `get_commits_with_artifacts` is relative to the current time. + let now = chrono::offset::Utc::now(); + connection + .record_commit(&Commit { + sha: "eebdfb55fce148676c24555505aebf648123b2de".to_string(), + parent_sha: "73f40197ecabf77ed59028af61739404eb60dd2e".to_string(), + time: now.into(), + pr: Some(108228), + }) + .await + .unwrap(); + + // A little older to ensure sorting is consistent. + let now3 = now - chrono::Duration::hours(3); + connection + .record_commit(&Commit { + sha: "73f40197ecabf77ed59028af61739404eb60dd2e".to_string(), + parent_sha: "fcdbd1c07f0b6c8e7d8bbd727c6ca69a1af8c7e9".to_string(), + time: now3.into(), + pr: Some(107772), + }) + .await + .unwrap(); + + // In the distant past, won't show up in get_commits_with_artifacts. + connection + .record_commit(&Commit { + sha: "26904687275a55864f32f3a7ba87b7711d063fd5".to_string(), + parent_sha: "3b348d932aa5c9884310d025cf7c516023fd0d9a".to_string(), + time: "2022-02-19T23:25:06Z".parse().unwrap(), + pr: Some(92911), + }) + .await + .unwrap(); + + assert!(connection + .has_commit("eebdfb55fce148676c24555505aebf648123b2de") + .await + .unwrap()); + assert!(connection + .has_commit("73f40197ecabf77ed59028af61739404eb60dd2e") + .await + .unwrap()); + assert!(connection + .has_commit("26904687275a55864f32f3a7ba87b7711d063fd5") + .await + .unwrap()); + assert!(!connection + .has_commit("fcdbd1c07f0b6c8e7d8bbd727c6ca69a1af8c7e9") + .await + .unwrap()); + + let missing = connection.get_missing_commits().await.unwrap(); + assert_eq!( + &missing[..], + [ + "fcdbd1c07f0b6c8e7d8bbd727c6ca69a1af8c7e9", + "3b348d932aa5c9884310d025cf7c516023fd0d9a" + ] + ); + + let commits = connection.get_commits_with_artifacts().await.unwrap(); + assert_eq!(commits.len(), 2); + assert_eq!(commits[0].sha, "eebdfb55fce148676c24555505aebf648123b2de"); + assert_eq!( + commits[0].parent_sha, + "73f40197ecabf77ed59028af61739404eb60dd2e" + ); + assert_datetime_approx_equal(&commits[0].time, &now); + assert_eq!(commits[0].pr, Some(108228)); + + assert_eq!(commits[1].sha, "73f40197ecabf77ed59028af61739404eb60dd2e"); + assert_eq!( + commits[1].parent_sha, + "fcdbd1c07f0b6c8e7d8bbd727c6ca69a1af8c7e9" + ); + assert_datetime_approx_equal(&commits[1].time, &now3); + assert_eq!(commits[1].pr, Some(107772)); + }); +} diff --git a/tests/github_client/bors_commits/00-GET-repos_rust-lang_rust_commits.json b/tests/github_client/bors_commits/00-GET-repos_rust-lang_rust_commits.json new file mode 100644 index 00000000..b0658429 --- /dev/null +++ b/tests/github_client/bors_commits/00-GET-repos_rust-lang_rust_commits.json @@ -0,0 +1,2530 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust/commits", + "query": "author=bors", + "request_body": "", + "response_code": 200, + "response_body": [ + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/7f97aeaf73047268299ab55288b3dd886130be47/comments", + "commit": { + "author": { + "date": "2023-02-05T11:10:11Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-05T11:10:11Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107679 - est31:less_import_overhead, r=compiler-errors\n\nLess import overhead for errors\n\nThis removes huge (3+ lines) import lists found in files that had their error reporting migrated. These lists are bad for developer workflows as adding, removing, or editing a single error's name might cause a chain reaction that bloats the git diff. As the error struct names are long, the likelihood of such chain reactions is high.\n\nFollows the suggestion by `@Nilstrieb` in the [zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/147480-t-compiler.2Fwg-diagnostics/topic/massive.20use.20statements) to replace the `use errors::{FooErr, BarErr};` with `use errors;` and then changing to `errors::FooErr` on the usage sites.\n\nI have used sed to do most of the changes, i.e. something like:\n\n```\nsed -i -E 's/(create_err|create_feature_err|emit_err|create_note|emit_fatal|emit_warning)\\(([[:alnum:]]+|[A-Z][[:alnum:]:]*)( \\{|\\))/\\1(errors::\\2\\3/' path/to/file.rs\n```\n\n& then I manually fixed the errors that occured. Most manual changes were required in `compiler/rustc_parse/src/parser/expr.rs`.\n\nr? `@compiler-errors`", + "tree": { + "sha": "28ef3869cb8034a8ab5e4ad389c139ec7dbd6df1", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/28ef3869cb8034a8ab5e4ad389c139ec7dbd6df1" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/7f97aeaf73047268299ab55288b3dd886130be47", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/7f97aeaf73047268299ab55288b3dd886130be47", + "node_id": "C_kwDOAAsO6NoAKDdmOTdhZWFmNzMwNDcyNjgyOTlhYjU1Mjg4YjNkZDg4NjEzMGJlNDc", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/2a6ff729233c62d1d991da5ed4d01aa29e59d637", + "sha": "2a6ff729233c62d1d991da5ed4d01aa29e59d637", + "url": "https://api.github.com/repos/rust-lang/rust/commits/2a6ff729233c62d1d991da5ed4d01aa29e59d637" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/580cc89e9c36a89d3cc13a352c96f874eaa76581", + "sha": "580cc89e9c36a89d3cc13a352c96f874eaa76581", + "url": "https://api.github.com/repos/rust-lang/rust/commits/580cc89e9c36a89d3cc13a352c96f874eaa76581" + } + ], + "sha": "7f97aeaf73047268299ab55288b3dd886130be47", + "url": "https://api.github.com/repos/rust-lang/rust/commits/7f97aeaf73047268299ab55288b3dd886130be47" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/2a6ff729233c62d1d991da5ed4d01aa29e59d637/comments", + "commit": { + "author": { + "date": "2023-02-05T07:36:37Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-05T07:36:37Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107434 - BoxyUwU:nll_const_equate, r=compiler-errors\n\nemit `ConstEquate` in `TypeRelating`\n\nemitting `ConstEquate` during mir typeck is useful since it can help catch bugs in hir typeck incase our impl of `ConstEquate` is wrong.\n\ndoing this did actually catch a bug, when relating `Expr::Call` we `==` the types of all the argument consts which spuriously returns false if the type contains const projections/aliases which causes us to fall through to the `expected_found` error arm.\nGenerally its an ICE if the `Const`'s `Ty`s arent equal but `ConstKind::Expr` is kind of special since they are sort of like const items that are `const CALL` though we dont actually explicitly represent the `F` type param explicitly in `Expr::Call` so I just made us relate the `Const`'s ty field to avoid getting ICEs from the tests I added and the following existing test:\n```rust\n// tests/ui/const-generics/generic_const_exprs/different-fn.rs\n#![feature(generic_const_exprs)]\n#![allow(incomplete_features)]\n\nuse std::mem::size_of;\nuse std::marker::PhantomData;\n\nstruct Foo(PhantomData);\n\nfn test() -> [u8; size_of::()] {\n [0; size_of::>()]\n //~^ ERROR unconstrained generic constant\n //~| ERROR mismatched types\n}\n\nfn main() {\n test::();\n}\n```\nwhich has us relate two `ConstKind::Value` one for the fn item of `size_of::>` and one for the fn item of `size_of::()`, these only differ by their `Ty` and if we don't relate the `Ty` we'll end up getting an ICE from the checks that ensure the `ty` fields always match.\n\nIn theory `Expr::UnOp` has the same problem so I added a call to `relate` for the ty's, although I was unable to create a repro test.", + "tree": { + "sha": "2304fe8c3bff131573b1cd5e6de1b3fb1c0ce7ad", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/2304fe8c3bff131573b1cd5e6de1b3fb1c0ce7ad" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/2a6ff729233c62d1d991da5ed4d01aa29e59d637", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/2a6ff729233c62d1d991da5ed4d01aa29e59d637", + "node_id": "C_kwDOAAsO6NoAKDJhNmZmNzI5MjMzYzYyZDFkOTkxZGE1ZWQ0ZDAxYWEyOWU1OWQ2Mzc", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/50d3ba5bcbf5c7e13d4ce068d3339710701dd603", + "sha": "50d3ba5bcbf5c7e13d4ce068d3339710701dd603", + "url": "https://api.github.com/repos/rust-lang/rust/commits/50d3ba5bcbf5c7e13d4ce068d3339710701dd603" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/d85d906f8c44dd98bf6bc0e4b753aa241839c323", + "sha": "d85d906f8c44dd98bf6bc0e4b753aa241839c323", + "url": "https://api.github.com/repos/rust-lang/rust/commits/d85d906f8c44dd98bf6bc0e4b753aa241839c323" + } + ], + "sha": "2a6ff729233c62d1d991da5ed4d01aa29e59d637", + "url": "https://api.github.com/repos/rust-lang/rust/commits/2a6ff729233c62d1d991da5ed4d01aa29e59d637" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/50d3ba5bcbf5c7e13d4ce068d3339710701dd603/comments", + "commit": { + "author": { + "date": "2023-02-04T21:07:10Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-04T21:07:10Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107672 - matthiaskrgr:rollup-7e6dbuk, r=matthiaskrgr\n\nRollup of 3 pull requests\n\nSuccessful merges:\n\n - #107116 (consolidate bootstrap docs)\n - #107646 (Provide structured suggestion for binding needing type on E0594)\n - #107661 (Remove Esteban from review queues for a while)\n\nFailed merges:\n\nr? `@ghost`\n`@rustbot` modify labels: rollup", + "tree": { + "sha": "932463b8bde694e38b6ed2bd27d772fc2ce0255f", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/932463b8bde694e38b6ed2bd27d772fc2ce0255f" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/50d3ba5bcbf5c7e13d4ce068d3339710701dd603", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/50d3ba5bcbf5c7e13d4ce068d3339710701dd603", + "node_id": "C_kwDOAAsO6NoAKDUwZDNiYTViY2JmNWM3ZTEzZDRjZTA2OGQzMzM5NzEwNzAxZGQ2MDM", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/3de7d7fb22a579a3d59ddb1c959d1b3da224aafa", + "sha": "3de7d7fb22a579a3d59ddb1c959d1b3da224aafa", + "url": "https://api.github.com/repos/rust-lang/rust/commits/3de7d7fb22a579a3d59ddb1c959d1b3da224aafa" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/47fc625a921aed430c08d6015246e65362256343", + "sha": "47fc625a921aed430c08d6015246e65362256343", + "url": "https://api.github.com/repos/rust-lang/rust/commits/47fc625a921aed430c08d6015246e65362256343" + } + ], + "sha": "50d3ba5bcbf5c7e13d4ce068d3339710701dd603", + "url": "https://api.github.com/repos/rust-lang/rust/commits/50d3ba5bcbf5c7e13d4ce068d3339710701dd603" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/3de7d7fb22a579a3d59ddb1c959d1b3da224aafa/comments", + "commit": { + "author": { + "date": "2023-02-04T18:11:02Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-04T18:11:02Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107549 - Zoxc:rustc-shared, r=jyn514\n\nMove code in `rustc_driver` out to a new `rustc_driver_impl` crate to allow pipelining\n\nThat adds a `rustc_shared` library which contains all the rustc library crates in a single dylib. It takes over this role from `rustc_driver`. This is done so that `rustc_driver` can be compiled in parallel with other crates. `rustc_shared` is intentionally left empty so it only does linking.\n\nAn alternative could be to move the code currently in `rustc_driver` into a new crate to avoid changing the name of the distributed library.", + "tree": { + "sha": "0d3e9447ea00657b717fbba42f6a854bc0b95355", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/0d3e9447ea00657b717fbba42f6a854bc0b95355" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/3de7d7fb22a579a3d59ddb1c959d1b3da224aafa", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/3de7d7fb22a579a3d59ddb1c959d1b3da224aafa", + "node_id": "C_kwDOAAsO6NoAKDNkZTdkN2ZiMjJhNTc5YTNkNTlkZGIxYzk1OWQxYjNkYTIyNGFhZmE", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/9dee4e4c42d23b0c5afd6d8fed025181f70fbe12", + "sha": "9dee4e4c42d23b0c5afd6d8fed025181f70fbe12", + "url": "https://api.github.com/repos/rust-lang/rust/commits/9dee4e4c42d23b0c5afd6d8fed025181f70fbe12" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/2b8f8922ee5852f97e92082b209c0f4d940a6edb", + "sha": "2b8f8922ee5852f97e92082b209c0f4d940a6edb", + "url": "https://api.github.com/repos/rust-lang/rust/commits/2b8f8922ee5852f97e92082b209c0f4d940a6edb" + } + ], + "sha": "3de7d7fb22a579a3d59ddb1c959d1b3da224aafa", + "url": "https://api.github.com/repos/rust-lang/rust/commits/3de7d7fb22a579a3d59ddb1c959d1b3da224aafa" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/9dee4e4c42d23b0c5afd6d8fed025181f70fbe12/comments", + "commit": { + "author": { + "date": "2023-02-04T15:17:32Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-04T15:17:32Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107267 - cjgillot:keep-aggregate, r=oli-obk\n\nDo not deaggregate MIR\n\nThis turns out to simplify a lot of things.\nI haven't checked the consequences for miri yet.\n\ncc `@JakobDegen`\nr? `@oli-obk`", + "tree": { + "sha": "9e854d084f562af0f8369eca144ad1fb044b248f", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/9e854d084f562af0f8369eca144ad1fb044b248f" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/9dee4e4c42d23b0c5afd6d8fed025181f70fbe12", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/9dee4e4c42d23b0c5afd6d8fed025181f70fbe12", + "node_id": "C_kwDOAAsO6NoAKDlkZWU0ZTRjNDJkMjNiMGM1YWZkNmQ4ZmVkMDI1MTgxZjcwZmJlMTI", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/4aa6afa7f8a418a7dae5dbe4c95371d4f3bcc0e1", + "sha": "4aa6afa7f8a418a7dae5dbe4c95371d4f3bcc0e1", + "url": "https://api.github.com/repos/rust-lang/rust/commits/4aa6afa7f8a418a7dae5dbe4c95371d4f3bcc0e1" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/5c39ba20279e338e2cd421bc799d4a5d3397c3b9", + "sha": "5c39ba20279e338e2cd421bc799d4a5d3397c3b9", + "url": "https://api.github.com/repos/rust-lang/rust/commits/5c39ba20279e338e2cd421bc799d4a5d3397c3b9" + } + ], + "sha": "9dee4e4c42d23b0c5afd6d8fed025181f70fbe12", + "url": "https://api.github.com/repos/rust-lang/rust/commits/9dee4e4c42d23b0c5afd6d8fed025181f70fbe12" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/4aa6afa7f8a418a7dae5dbe4c95371d4f3bcc0e1/comments", + "commit": { + "author": { + "date": "2023-02-04T11:22:31Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-04T11:22:31Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107618 - chriswailes:linker-arg, r=albertlarsan68\n\nAdd a linker argument back to boostrap.py\n\nIn https://github.com/rust-lang/rust/pull/101783 I accidentally removed a load-bearing linker argument. This PR adds it back in.\n\nr? jyn514", + "tree": { + "sha": "eac1bf39849eae33d4bb2b9bdb80304e8a03dd48", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/eac1bf39849eae33d4bb2b9bdb80304e8a03dd48" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/4aa6afa7f8a418a7dae5dbe4c95371d4f3bcc0e1", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/4aa6afa7f8a418a7dae5dbe4c95371d4f3bcc0e1", + "node_id": "C_kwDOAAsO6NoAKDRhYTZhZmE3ZjhhNDE4YTdkYWU1ZGJlNGM5NTM3MWQ0ZjNiY2MwZTE", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/91eb6f9acfcfde6832d547959ad2d95b1ac0b5dc", + "sha": "91eb6f9acfcfde6832d547959ad2d95b1ac0b5dc", + "url": "https://api.github.com/repos/rust-lang/rust/commits/91eb6f9acfcfde6832d547959ad2d95b1ac0b5dc" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/134a5aea52641715dd1ea1e4ad0e6a5693fbedc6", + "sha": "134a5aea52641715dd1ea1e4ad0e6a5693fbedc6", + "url": "https://api.github.com/repos/rust-lang/rust/commits/134a5aea52641715dd1ea1e4ad0e6a5693fbedc6" + } + ], + "sha": "4aa6afa7f8a418a7dae5dbe4c95371d4f3bcc0e1", + "url": "https://api.github.com/repos/rust-lang/rust/commits/4aa6afa7f8a418a7dae5dbe4c95371d4f3bcc0e1" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/91eb6f9acfcfde6832d547959ad2d95b1ac0b5dc/comments", + "commit": { + "author": { + "date": "2023-02-04T03:41:57Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-04T03:41:57Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107591 - krasimirgg:llvm-17-pgoopts, r=cuviper\n\nllvm-wrapper: adapt for LLVM API changes\n\nAdapts the wrapper for https://github.com/llvm/llvm-project/commit/516e301752560311d2cd8c2b549493eb0f98d01b, where the constructor of PGOOptions gained a new FileSystem argument. Adapted to use the real file system, similarly to the changes inside of LLVM:\nhttps://github.com/llvm/llvm-project/commit/516e301752560311d2cd8c2b549493eb0f98d01b#diff-f409934ba27ad86494f3012324e9a3995b56e0743609ded7a387ba62bbf5edb0R236\n\nFound via our experimental Rust + LLVM at HEAD bot: https://buildkite.com/llvm-project/rust-llvm-integrate-prototype/builds/16853#01860e2e-5eba-4f07-8359-0325913ff410/219-517", + "tree": { + "sha": "eac1bf39849eae33d4bb2b9bdb80304e8a03dd48", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/eac1bf39849eae33d4bb2b9bdb80304e8a03dd48" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/91eb6f9acfcfde6832d547959ad2d95b1ac0b5dc", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/91eb6f9acfcfde6832d547959ad2d95b1ac0b5dc", + "node_id": "C_kwDOAAsO6NoAKDkxZWI2ZjlhY2ZjZmRlNjgzMmQ1NDc5NTlhZDJkOTViMWFjMGI1ZGM", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/886b2c3e005b153b3c8263f48193e0df7de0f5b3", + "sha": "886b2c3e005b153b3c8263f48193e0df7de0f5b3", + "url": "https://api.github.com/repos/rust-lang/rust/commits/886b2c3e005b153b3c8263f48193e0df7de0f5b3" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/4614e5b5bf1331907bf3baf70cf0eb705f2959e9", + "sha": "4614e5b5bf1331907bf3baf70cf0eb705f2959e9", + "url": "https://api.github.com/repos/rust-lang/rust/commits/4614e5b5bf1331907bf3baf70cf0eb705f2959e9" + } + ], + "sha": "91eb6f9acfcfde6832d547959ad2d95b1ac0b5dc", + "url": "https://api.github.com/repos/rust-lang/rust/commits/91eb6f9acfcfde6832d547959ad2d95b1ac0b5dc" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/886b2c3e005b153b3c8263f48193e0df7de0f5b3/comments", + "commit": { + "author": { + "date": "2023-02-03T22:37:53Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-03T22:37:53Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107650 - compiler-errors:rollup-4pntchf, r=compiler-errors\n\nRollup of 8 pull requests\n\nSuccessful merges:\n\n - #106887 (Make const/fn return params more suggestable)\n - #107519 (Add type alias for raw OS errors)\n - #107551 ( Replace `ConstFnMutClosure` with const closures )\n - #107595 (Retry opening proc-macro DLLs a few times on Windows.)\n - #107615 (Replace nbsp in all rustdoc code blocks)\n - #107621 (Intern external constraints in new solver)\n - #107631 (loudly tell people when they change `Cargo.lock`)\n - #107632 (Clarifying that .map() returns None if None.)\n\nFailed merges:\n\nr? `@ghost`\n`@rustbot` modify labels: rollup", + "tree": { + "sha": "4bd560ab45691d951ce6a3b70229091e093a69b7", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/4bd560ab45691d951ce6a3b70229091e093a69b7" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/886b2c3e005b153b3c8263f48193e0df7de0f5b3", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/886b2c3e005b153b3c8263f48193e0df7de0f5b3", + "node_id": "C_kwDOAAsO6NoAKDg4NmIyYzNlMDA1YjE1M2IzYzgyNjNmNDgxOTNlMGRmN2RlMGY1YjM", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/658fad6c5506f41c35b64fb1a22ceb0992697ff3", + "sha": "658fad6c5506f41c35b64fb1a22ceb0992697ff3", + "url": "https://api.github.com/repos/rust-lang/rust/commits/658fad6c5506f41c35b64fb1a22ceb0992697ff3" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/13bd75f425f084d63817336db5ca433bc0655786", + "sha": "13bd75f425f084d63817336db5ca433bc0655786", + "url": "https://api.github.com/repos/rust-lang/rust/commits/13bd75f425f084d63817336db5ca433bc0655786" + } + ], + "sha": "886b2c3e005b153b3c8263f48193e0df7de0f5b3", + "url": "https://api.github.com/repos/rust-lang/rust/commits/886b2c3e005b153b3c8263f48193e0df7de0f5b3" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/658fad6c5506f41c35b64fb1a22ceb0992697ff3/comments", + "commit": { + "author": { + "date": "2023-02-03T17:53:49Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-03T17:53:49Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107642 - Dylan-DPC:rollup-edcqhm5, r=Dylan-DPC\n\nRollup of 6 pull requests\n\nSuccessful merges:\n\n - #107082 (Autotrait bounds on dyn-safe trait methods)\n - #107427 (Add candidates for DiscriminantKind builtin)\n - #107539 (Emit warnings on unused parens in index expressions)\n - #107544 (Improve `TokenCursor`.)\n - #107585 (Don't cause a cycle when formatting query description that references a FnDef)\n - #107633 (Fix suggestion for coercing Option<&String> to Option<&str>)\n\nFailed merges:\n\nr? `@ghost`\n`@rustbot` modify labels: rollup", + "tree": { + "sha": "d9beffb3e496848ea5acbe6d9caf2d102f473eab", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/d9beffb3e496848ea5acbe6d9caf2d102f473eab" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/658fad6c5506f41c35b64fb1a22ceb0992697ff3", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/658fad6c5506f41c35b64fb1a22ceb0992697ff3", + "node_id": "C_kwDOAAsO6NoAKDY1OGZhZDZjNTUwNmY0MWMzNWI2NGZiMWEyMmNlYjA5OTI2OTdmZjM", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/9545094994f1ab45cab5799d5b45980871a9e97b", + "sha": "9545094994f1ab45cab5799d5b45980871a9e97b", + "url": "https://api.github.com/repos/rust-lang/rust/commits/9545094994f1ab45cab5799d5b45980871a9e97b" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/c9270272df5bd7254b6ce1c7b69d41c75e443406", + "sha": "c9270272df5bd7254b6ce1c7b69d41c75e443406", + "url": "https://api.github.com/repos/rust-lang/rust/commits/c9270272df5bd7254b6ce1c7b69d41c75e443406" + } + ], + "sha": "658fad6c5506f41c35b64fb1a22ceb0992697ff3", + "url": "https://api.github.com/repos/rust-lang/rust/commits/658fad6c5506f41c35b64fb1a22ceb0992697ff3" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/9545094994f1ab45cab5799d5b45980871a9e97b/comments", + "commit": { + "author": { + "date": "2023-02-03T14:22:42Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-03T14:22:42Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107599 - clubby789:debug-less-ref, r=nnethercote\n\nDon't generate unecessary `&&self.field` in deriving Debug\n\nSince unsized fields may only be the last one in a struct, we only need to generate a double reference (`&&self.field`) for the final one.\n\ncc `@nnethercote`", + "tree": { + "sha": "f20e2d08b8836fe5498948b0863680019083975c", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/f20e2d08b8836fe5498948b0863680019083975c" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/9545094994f1ab45cab5799d5b45980871a9e97b", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/9545094994f1ab45cab5799d5b45980871a9e97b", + "node_id": "C_kwDOAAsO6NoAKDk1NDUwOTQ5OTRmMWFiNDVjYWI1Nzk5ZDViNDU5ODA4NzFhOWU5N2I", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/a94b9fd0ace1336a3dd93f51f1c0db6ca0fd7f92", + "sha": "a94b9fd0ace1336a3dd93f51f1c0db6ca0fd7f92", + "url": "https://api.github.com/repos/rust-lang/rust/commits/a94b9fd0ace1336a3dd93f51f1c0db6ca0fd7f92" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/d8651aae22d3b2251045647e7313fea37381362a", + "sha": "d8651aae22d3b2251045647e7313fea37381362a", + "url": "https://api.github.com/repos/rust-lang/rust/commits/d8651aae22d3b2251045647e7313fea37381362a" + } + ], + "sha": "9545094994f1ab45cab5799d5b45980871a9e97b", + "url": "https://api.github.com/repos/rust-lang/rust/commits/9545094994f1ab45cab5799d5b45980871a9e97b" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/a94b9fd0ace1336a3dd93f51f1c0db6ca0fd7f92/comments", + "commit": { + "author": { + "date": "2023-02-03T11:19:03Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-03T11:19:03Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107569 - petrochenkov:optattr, r=nnethercote\n\nast: Optimize list and value extraction primitives for attributes\n\nIt's not necessary to convert the whole attribute into a meta item to extract something specific.", + "tree": { + "sha": "a2064cce0219090bcdba2de58a84a62b78fc0270", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/a2064cce0219090bcdba2de58a84a62b78fc0270" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/a94b9fd0ace1336a3dd93f51f1c0db6ca0fd7f92", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/a94b9fd0ace1336a3dd93f51f1c0db6ca0fd7f92", + "node_id": "C_kwDOAAsO6NoAKGE5NGI5ZmQwYWNlMTMzNmEzZGQ5M2Y1MWYxYzBkYjZjYTBmZDdmOTI", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/7c46fb2111936ad21a8e3aa41e9128752357f5d8", + "sha": "7c46fb2111936ad21a8e3aa41e9128752357f5d8", + "url": "https://api.github.com/repos/rust-lang/rust/commits/7c46fb2111936ad21a8e3aa41e9128752357f5d8" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/a9c8a5c0255d056f78f1347c431fd88bc727febb", + "sha": "a9c8a5c0255d056f78f1347c431fd88bc727febb", + "url": "https://api.github.com/repos/rust-lang/rust/commits/a9c8a5c0255d056f78f1347c431fd88bc727febb" + } + ], + "sha": "a94b9fd0ace1336a3dd93f51f1c0db6ca0fd7f92", + "url": "https://api.github.com/repos/rust-lang/rust/commits/a94b9fd0ace1336a3dd93f51f1c0db6ca0fd7f92" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/7c46fb2111936ad21a8e3aa41e9128752357f5d8/comments", + "commit": { + "author": { + "date": "2023-02-03T08:07:47Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-03T08:07:47Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107625 - matthiaskrgr:rollup-xr9oldy, r=matthiaskrgr\n\nRollup of 6 pull requests\n\nSuccessful merges:\n\n - #106575 (Suggest `move` in nested closure when appropriate)\n - #106805 (Suggest `{var:?}` when finding `{?:var}` in inline format strings)\n - #107500 (Add tests to assert current behavior of large future sizes)\n - #107598 (Fix benchmarks in library/core with black_box)\n - #107602 (Parse and recover from type ascription in patterns)\n - #107608 (Use triple rather than arch for fuchsia test-runner)\n\nFailed merges:\n\nr? `@ghost`\n`@rustbot` modify labels: rollup", + "tree": { + "sha": "d3bdac647485a029e043f15ab0b46529058a437c", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/d3bdac647485a029e043f15ab0b46529058a437c" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/7c46fb2111936ad21a8e3aa41e9128752357f5d8", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/7c46fb2111936ad21a8e3aa41e9128752357f5d8", + "node_id": "C_kwDOAAsO6NoAKDdjNDZmYjIxMTE5MzZhZDIxYThlM2FhNDFlOTEyODc1MjM1N2Y1ZDg", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/5d32458343f34bd8de6d96cbaab2a9cf879dd1b8", + "sha": "5d32458343f34bd8de6d96cbaab2a9cf879dd1b8", + "url": "https://api.github.com/repos/rust-lang/rust/commits/5d32458343f34bd8de6d96cbaab2a9cf879dd1b8" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/b6e8ebf33b0203ab16bbb26eb95a6654ee00ac8e", + "sha": "b6e8ebf33b0203ab16bbb26eb95a6654ee00ac8e", + "url": "https://api.github.com/repos/rust-lang/rust/commits/b6e8ebf33b0203ab16bbb26eb95a6654ee00ac8e" + } + ], + "sha": "7c46fb2111936ad21a8e3aa41e9128752357f5d8", + "url": "https://api.github.com/repos/rust-lang/rust/commits/7c46fb2111936ad21a8e3aa41e9128752357f5d8" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/5d32458343f34bd8de6d96cbaab2a9cf879dd1b8/comments", + "commit": { + "author": { + "date": "2023-02-03T04:49:50Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-03T04:49:50Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107543 - ehuss:protocol-sparse, r=jyn514\n\nEnable Cargo's sparse protocol in CI\n\nThis enables the sparse protocol in CI in order to exercise and dogfood it. This is intended test the production server in a real-world situation.\n\nCloses #107342", + "tree": { + "sha": "9c2f45b42f042b5f78bfd1b8c491958f83dd1351", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/9c2f45b42f042b5f78bfd1b8c491958f83dd1351" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/5d32458343f34bd8de6d96cbaab2a9cf879dd1b8", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/5d32458343f34bd8de6d96cbaab2a9cf879dd1b8", + "node_id": "C_kwDOAAsO6NoAKDVkMzI0NTgzNDNmMzRiZDhkZTZkOTZjYmFhYjJhOWNmODc5ZGQxYjg", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/f02439dea78e5c2df42198c7a03e2db6002ff263", + "sha": "f02439dea78e5c2df42198c7a03e2db6002ff263", + "url": "https://api.github.com/repos/rust-lang/rust/commits/f02439dea78e5c2df42198c7a03e2db6002ff263" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/5e90940a4b742e7f1e86f21c26b56e99a8733458", + "sha": "5e90940a4b742e7f1e86f21c26b56e99a8733458", + "url": "https://api.github.com/repos/rust-lang/rust/commits/5e90940a4b742e7f1e86f21c26b56e99a8733458" + } + ], + "sha": "5d32458343f34bd8de6d96cbaab2a9cf879dd1b8", + "url": "https://api.github.com/repos/rust-lang/rust/commits/5d32458343f34bd8de6d96cbaab2a9cf879dd1b8" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/f02439dea78e5c2df42198c7a03e2db6002ff263/comments", + "commit": { + "author": { + "date": "2023-02-03T01:19:04Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-03T01:19:04Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107241 - clubby789:bootstrap-lto-off, r=simulacrum\n\nAdd `rust.lto=off` to bootstrap and set as compiler/library default\n\nCloses #107202\n\nThe issue mentions `embed-bitcode=on`, but here https://github.com/rust-lang/rust/blob/c8e6a9e8b6251bbc8276cb78cabe1998deecbed7/src/bootstrap/compile.rs#L379-L381\nit appears that this is always set for std stage 1+, so I'm unsure if changes are needed here.\n\n`@rustbot` label +A-bootstrap", + "tree": { + "sha": "ba934c044e040c794ecaf64c5d0ddea604210a5c", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/ba934c044e040c794ecaf64c5d0ddea604210a5c" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/f02439dea78e5c2df42198c7a03e2db6002ff263", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/f02439dea78e5c2df42198c7a03e2db6002ff263", + "node_id": "C_kwDOAAsO6NoAKGYwMjQzOWRlYTc4ZTVjMmRmNDIxOThjN2EwM2UyZGI2MDAyZmYyNjM", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/6c991b07403a3234dd1ec0ac973b8ef97055e605", + "sha": "6c991b07403a3234dd1ec0ac973b8ef97055e605", + "url": "https://api.github.com/repos/rust-lang/rust/commits/6c991b07403a3234dd1ec0ac973b8ef97055e605" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/2adf26fc72f354aabd65da176eb9f8806b0d2ef2", + "sha": "2adf26fc72f354aabd65da176eb9f8806b0d2ef2", + "url": "https://api.github.com/repos/rust-lang/rust/commits/2adf26fc72f354aabd65da176eb9f8806b0d2ef2" + } + ], + "sha": "f02439dea78e5c2df42198c7a03e2db6002ff263", + "url": "https://api.github.com/repos/rust-lang/rust/commits/f02439dea78e5c2df42198c7a03e2db6002ff263" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/6c991b07403a3234dd1ec0ac973b8ef97055e605/comments", + "commit": { + "author": { + "date": "2023-02-02T21:14:44Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-02T21:14:44Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107000 - GuillaumeGomez:fix-items-in-doc-hidden-block, r=notriddle,petrochenkov\n\nFix handling of items inside a `doc(hidden)` block\n\nFixes #106373.\n\ncc `@aDotInTheVoid`\nr? `@notriddle`", + "tree": { + "sha": "e9fd955533d898249d8602ae2e2cc9b6040b264b", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/e9fd955533d898249d8602ae2e2cc9b6040b264b" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/6c991b07403a3234dd1ec0ac973b8ef97055e605", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/6c991b07403a3234dd1ec0ac973b8ef97055e605", + "node_id": "C_kwDOAAsO6NoAKDZjOTkxYjA3NDAzYTMyMzRkZDFlYzBhYzk3M2I4ZWY5NzA1NWU2MDU", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/f3126500f25114ba4e0ac3e76694dd45a22de56d", + "sha": "f3126500f25114ba4e0ac3e76694dd45a22de56d", + "url": "https://api.github.com/repos/rust-lang/rust/commits/f3126500f25114ba4e0ac3e76694dd45a22de56d" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/ea844187b27fbcff521bcbcbe6615d51d0196fa2", + "sha": "ea844187b27fbcff521bcbcbe6615d51d0196fa2", + "url": "https://api.github.com/repos/rust-lang/rust/commits/ea844187b27fbcff521bcbcbe6615d51d0196fa2" + } + ], + "sha": "6c991b07403a3234dd1ec0ac973b8ef97055e605", + "url": "https://api.github.com/repos/rust-lang/rust/commits/6c991b07403a3234dd1ec0ac973b8ef97055e605" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/f3126500f25114ba4e0ac3e76694dd45a22de56d/comments", + "commit": { + "author": { + "date": "2023-02-02T17:56:53Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-02T17:56:53Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107601 - matthiaskrgr:rollup-07zaafe, r=matthiaskrgr\n\nRollup of 7 pull requests\n\nSuccessful merges:\n\n - #106919 (Recover `_` as `..` in field pattern)\n - #107493 (Improve diagnostic for missing space in range pattern)\n - #107515 (Improve pretty-printing of `HirIdValidator` errors)\n - #107524 (Remove both StorageLive and StorageDead in CopyProp.)\n - #107532 (Erase regions before doing uninhabited check in borrowck)\n - #107559 (Rename `rust_2015` → `is_rust_2015`)\n - #107577 (Reinstate the `hir-stats.rs` tests on stage 1.)\n\nFailed merges:\n\nr? `@ghost`\n`@rustbot` modify labels: rollup", + "tree": { + "sha": "ab016ef14231c6193f6a9d086fca0cda4a159f9a", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/ab016ef14231c6193f6a9d086fca0cda4a159f9a" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/f3126500f25114ba4e0ac3e76694dd45a22de56d", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/f3126500f25114ba4e0ac3e76694dd45a22de56d", + "node_id": "C_kwDOAAsO6NoAKGYzMTI2NTAwZjI1MTE0YmE0ZTBhYzNlNzY2OTRkZDQ1YTIyZGU1NmQ", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/97872b792c9dd6a9bc5c3f4e62a0bd5958b09cdc", + "sha": "97872b792c9dd6a9bc5c3f4e62a0bd5958b09cdc", + "url": "https://api.github.com/repos/rust-lang/rust/commits/97872b792c9dd6a9bc5c3f4e62a0bd5958b09cdc" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/08181eabfeb468e22e5ce179492979d57d0cdf85", + "sha": "08181eabfeb468e22e5ce179492979d57d0cdf85", + "url": "https://api.github.com/repos/rust-lang/rust/commits/08181eabfeb468e22e5ce179492979d57d0cdf85" + } + ], + "sha": "f3126500f25114ba4e0ac3e76694dd45a22de56d", + "url": "https://api.github.com/repos/rust-lang/rust/commits/f3126500f25114ba4e0ac3e76694dd45a22de56d" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/97872b792c9dd6a9bc5c3f4e62a0bd5958b09cdc/comments", + "commit": { + "author": { + "date": "2023-02-02T12:01:17Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-02T12:01:17Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107478 - compiler-errors:anon-enum-tys-are-ambiguous, r=estebank\n\nRevert \"Teach parser to understand fake anonymous enum syntax\" and related commits\n\nanonymous enum types are currently ambiguous in positions like:\n\n* `|` operator: `a as fn() -> B | C`\n* closure args: `|_: as fn() -> A | B`\n\nI first tried to thread around `RecoverAnonEnum` into all these positions, but the resulting complexity in the compiler is IMO not worth it, or at least worth a bit more thinking time. In the mean time, let's revert this syntax for now, so we can go back to the drawing board.\n\nFixes #107461\n\ncc: `@estebank` `@cjgillot` #106960\n\n---\n### Squashed revert commits:\n\nRevert \"review comment: Remove AST AnonTy\"\n\nThis reverts commit 020cca8d36cb678e3ddc2ead41364be314d19e93.\n\nRevert \"Ensure macros are not affected\"\n\nThis reverts commit 12d18e403139eeeeb339e8611b2bed4910864edb.\n\nRevert \"Emit fewer errors on patterns with possible type ascription\"\n\nThis reverts commit c847a01a3b1f620c4fdb98c75805033e768975d1.\n\nRevert \"Teach parser to understand fake anonymous enum syntax\"\n\nThis reverts commit 2d824206655bfb26cb5eed43490ee396542b153e.", + "tree": { + "sha": "ac382c6f916b98074fe5ce756d3778d5d3f0d407", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/ac382c6f916b98074fe5ce756d3778d5d3f0d407" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/97872b792c9dd6a9bc5c3f4e62a0bd5958b09cdc", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/97872b792c9dd6a9bc5c3f4e62a0bd5958b09cdc", + "node_id": "C_kwDOAAsO6NoAKDk3ODcyYjc5MmM5ZGQ2YTliYzVjM2Y0ZTYyYTBiZDU5NThiMDljZGM", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/a9985cf172e7cb8ab5c58ce2818752c3572754fc", + "sha": "a9985cf172e7cb8ab5c58ce2818752c3572754fc", + "url": "https://api.github.com/repos/rust-lang/rust/commits/a9985cf172e7cb8ab5c58ce2818752c3572754fc" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/39db65c526ae3b97f0ee90642242c8c07865707e", + "sha": "39db65c526ae3b97f0ee90642242c8c07865707e", + "url": "https://api.github.com/repos/rust-lang/rust/commits/39db65c526ae3b97f0ee90642242c8c07865707e" + } + ], + "sha": "97872b792c9dd6a9bc5c3f4e62a0bd5958b09cdc", + "url": "https://api.github.com/repos/rust-lang/rust/commits/97872b792c9dd6a9bc5c3f4e62a0bd5958b09cdc" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/a9985cf172e7cb8ab5c58ce2818752c3572754fc/comments", + "commit": { + "author": { + "date": "2023-02-02T09:05:18Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-02T09:05:18Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107584 - matthiaskrgr:rollup-vav4ljz, r=matthiaskrgr\n\nRollup of 5 pull requests\n\nSuccessful merges:\n\n - #107201 (Remove confusing 'while checking' note from opaque future type mismatches)\n - #107312 (Add Style Guide rules for let-else statements)\n - #107488 (Fix syntax in `-Zunpretty-expanded` output for derived `PartialEq`.)\n - #107531 (Inline CSS background images directly into the CSS)\n - #107576 (Add proc-macro boilerplate to crt-static test)\n\nFailed merges:\n\nr? `@ghost`\n`@rustbot` modify labels: rollup", + "tree": { + "sha": "dbb937247db20bbd75be7bde50d74213d674dbde", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/dbb937247db20bbd75be7bde50d74213d674dbde" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/a9985cf172e7cb8ab5c58ce2818752c3572754fc", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/a9985cf172e7cb8ab5c58ce2818752c3572754fc", + "node_id": "C_kwDOAAsO6NoAKGE5OTg1Y2YxNzJlN2NiOGFiNWM1OGNlMjgxODc1MmMzNTcyNzU0ZmM", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/821b2a8e39588fedda894d10b9b3abd7293f0383", + "sha": "821b2a8e39588fedda894d10b9b3abd7293f0383", + "url": "https://api.github.com/repos/rust-lang/rust/commits/821b2a8e39588fedda894d10b9b3abd7293f0383" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/643fc97fd3b3f4f34eb2d66af1deac9218835527", + "sha": "643fc97fd3b3f4f34eb2d66af1deac9218835527", + "url": "https://api.github.com/repos/rust-lang/rust/commits/643fc97fd3b3f4f34eb2d66af1deac9218835527" + } + ], + "sha": "a9985cf172e7cb8ab5c58ce2818752c3572754fc", + "url": "https://api.github.com/repos/rust-lang/rust/commits/a9985cf172e7cb8ab5c58ce2818752c3572754fc" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/821b2a8e39588fedda894d10b9b3abd7293f0383/comments", + "commit": { + "author": { + "date": "2023-02-02T05:26:09Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-02T05:26:09Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #106925 - imWildCat:imWildCat/remove-hardcoded-ios-macbi-target-version, r=wesleywiser\n\nRemove hardcoded iOS version of clang target for Mac Catalyst\n\n## Background\n\nFrom `clang` 13.x, `-target x86_64-apple-ios13.0-macabi` fails while linking:\n\n```\n = note: clang: error: invalid version number in '-target x86_64-apple-ios13.0-macabi'\n```\n\n

\nVerbose output\n\n```\nerror: linking with `cc` failed: exit status: 1\n |\n = note: LC_ALL=\"C\" PATH=\"[removed]\" VSLANG=\"1033\" ZERO_AR_DATE=\"1\" \"cc\" \"-Wl,-exported_symbols_list,/var/folders/p8/qpmzbsdn07g5gxykwfxxw7y40000gn/T/rustci8tkvp/list\" \"-target\" \"x86_64-apple-ios13.0-macabi\" \"/var/folders/p8/qpmzbsdn07g5gxykwfxxw7y40000gn/T/rustci8tkvp/symbols.o\" \"/path/to/my/[project]/[user]/target/x86_64-apple-ios-macabi/release/deps/[user].[user].a2ccc648-cgu.0.rcgu.o\" \"-L\" \"/path/to/my/[project]/[user]/target/x86_64-apple-ios-macabi/release/deps\" \"-L\" \"/path/to/my/[project]/[user]/target/release/deps\" \"-L\" \"/path/to/my/[project]/[user]/target/x86_64-apple-ios-macabi/release/build/blake3-74e6ba91506ce712/out\" \"-L\" \"/path/to/my/[project]/[user]/target/x86_64-apple-ios-macabi/release/build/blake3-74e6ba91506ce712/out\" \"-L\" \"/Users/[user]/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/x86_64-apple-ios-macabi/lib\" \"/var/folders/p8/qpmzbsdn07g5gxykwfxxw7y40000gn/T/rustci8tkvp/libblake3-343c1616c8f62c66.rlib\" \"/path/to/my/[project]/[user]/target/x86_64-apple-ios-macabi/release/deps/libcompiler_builtins-15d4f20b641cf9ef.rlib\" \"-framework\" \"Security\" \"-framework\" \"CoreFoundation\" \"-framework\" \"Security\" \"-liconv\" \"-lSystem\" \"-lobjc\" \"-framework\" \"Security\" \"-framework\" \"Foundation\" \"-lc\" \"-lm\" \"-isysroot\" \"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk\" \"-Wl,-syslibroot\" \"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk\" \"-L\" \"/Users/[user]/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/x86_64-apple-ios-macabi/lib\" \"-o\" \"/path/to/my/[project]/[user]/target/x86_64-apple-ios-macabi/release/deps/lib[user].dylib\" \"-Wl,-dead_strip\" \"-dynamiclib\" \"-Wl,-dylib\" \"-nodefaultlibs\"\n = note: clang: error: invalid version number in '-target x86_64-apple-ios13.0-macabi'\n\nwarning: `[user]` (lib) generated 6 warnings\nerror: could not compile `[user]` due to previous error; 6 warnings emitted\n```\n
\n\n### Minimal example\n\nC code:\n\n```c\n#include \nvoid main() {\n int a = 1;\n int b = 2;\n int c = a + b;\n printf(\"%d\", c);\n}\n```\n\n`clang` command sample:\n\n```\n➜ 202301 clang -target x86_64-apple-ios13.0-macabi main.c\nclang: error: invalid version number in '-target x86_64-apple-ios13.0-macabi'\n➜ 202301 clang -target x86_64-apple-ios14.0-macabi main.c\nmain.c:2:1: warning: return type of 'main' is not 'int' [-Wmain-return-type]\nvoid main() {\n^\nmain.c:2:1: note: change return type to 'int'\nvoid main() {\n^~~~\nint\n1 warning generated.\n➜ 202301 clang -target x86_64-apple-ios15.0-macabi main.c\nmain.c:2:1: warning: return type of 'main' is not 'int' [-Wmain-return-type]\nvoid main() {\n^\nmain.c:2:1: note: change return type to 'int'\nvoid main() {\n^~~~\nint\n1 warning generated.\n➜ 202301 clang -target x86_64-apple-ios-macabi main.c\nmain.c:2:1: warning: return type of 'main' is not 'int' [-Wmain-return-type]\nvoid main() {\n^\nmain.c:2:1: note: change return type to 'int'\nvoid main() {\n^~~~\nint\n1 warning generated.\n\n➜ 202301 clang --version\nApple clang version 14.0.0 (clang-1400.0.29.202)\nTarget: arm64-apple-darwin22.2.0\nThread model: posix\nInstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin\n```\n\nThis PR is a simplified version of #96392, inspired by https://github.com/rust-lang/cc-rs/pull/727", + "tree": { + "sha": "0f1eba14a5ae3fa1c9c700ec5d1b07c0dab8b554", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/0f1eba14a5ae3fa1c9c700ec5d1b07c0dab8b554" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/821b2a8e39588fedda894d10b9b3abd7293f0383", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/821b2a8e39588fedda894d10b9b3abd7293f0383", + "node_id": "C_kwDOAAsO6NoAKDgyMWIyYThlMzk1ODhmZWRkYTg5NGQxMGI5YjNhYmQ3MjkzZjAzODM", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/131f0c6df6777800aa884963bdba0739299cd31f", + "sha": "131f0c6df6777800aa884963bdba0739299cd31f", + "url": "https://api.github.com/repos/rust-lang/rust/commits/131f0c6df6777800aa884963bdba0739299cd31f" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/5209d6f5fdac2054666a15c64f78450d6cb99717", + "sha": "5209d6f5fdac2054666a15c64f78450d6cb99717", + "url": "https://api.github.com/repos/rust-lang/rust/commits/5209d6f5fdac2054666a15c64f78450d6cb99717" + } + ], + "sha": "821b2a8e39588fedda894d10b9b3abd7293f0383", + "url": "https://api.github.com/repos/rust-lang/rust/commits/821b2a8e39588fedda894d10b9b3abd7293f0383" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/131f0c6df6777800aa884963bdba0739299cd31f/comments", + "commit": { + "author": { + "date": "2023-02-02T02:23:31Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-02T02:23:31Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #105670 - Xiretza:rustc_parse-diagnostics-4, r=davidtwco\n\nrustc_parse: diagnostics migration, v4\n\nThis is all the `rustc_parse` migrations I have in store right now; unfortunately life is pretty busy right now, so I won't be able to do much more in the near future.\n\ncc #100717\n\nr? `@davidtwco`", + "tree": { + "sha": "44543518d5568584010021497a2e187328bf9b06", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/44543518d5568584010021497a2e187328bf9b06" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/131f0c6df6777800aa884963bdba0739299cd31f", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/131f0c6df6777800aa884963bdba0739299cd31f", + "node_id": "C_kwDOAAsO6NoAKDEzMWYwYzZkZjY3Nzc4MDBhYTg4NDk2M2JkYmEwNzM5Mjk5Y2QzMWY", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/8789e5392975203137765d7818fb23ad125782b3", + "sha": "8789e5392975203137765d7818fb23ad125782b3", + "url": "https://api.github.com/repos/rust-lang/rust/commits/8789e5392975203137765d7818fb23ad125782b3" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/0d0d36991599d230d4781432391608f9821765fa", + "sha": "0d0d36991599d230d4781432391608f9821765fa", + "url": "https://api.github.com/repos/rust-lang/rust/commits/0d0d36991599d230d4781432391608f9821765fa" + } + ], + "sha": "131f0c6df6777800aa884963bdba0739299cd31f", + "url": "https://api.github.com/repos/rust-lang/rust/commits/131f0c6df6777800aa884963bdba0739299cd31f" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/8789e5392975203137765d7818fb23ad125782b3/comments", + "commit": { + "author": { + "date": "2023-02-01T22:45:27Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-01T22:45:27Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107574 - compiler-errors:back-to-old-mac-builders-pls, r=pietroalbini\n\nRevert \"switch to the macos-12-xl builder\"\n\nThis reverts commit fcbae989ae790d5b9a0a23ceba242d0b0d4e6c5b.\n\nThis should fix the bors failures in https://rust-lang.zulipchat.com/#narrow/stream/242791-t-infra/topic/Every.20rust-lang.2Frust.20PR.20is.20failing.20bors", + "tree": { + "sha": "68f1f608bda41a90ec8a74295dbc3deb7e6c783c", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/68f1f608bda41a90ec8a74295dbc3deb7e6c783c" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/8789e5392975203137765d7818fb23ad125782b3", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/8789e5392975203137765d7818fb23ad125782b3", + "node_id": "C_kwDOAAsO6NoAKDg3ODllNTM5Mjk3NTIwMzEzNzc2NWQ3ODE4ZmIyM2FkMTI1NzgyYjM", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/11d96b59307b1702fffe871bfc2d0145d070881e", + "sha": "11d96b59307b1702fffe871bfc2d0145d070881e", + "url": "https://api.github.com/repos/rust-lang/rust/commits/11d96b59307b1702fffe871bfc2d0145d070881e" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/e63ec2e1402eaff949e5c53b8f6062b152010fcc", + "sha": "e63ec2e1402eaff949e5c53b8f6062b152010fcc", + "url": "https://api.github.com/repos/rust-lang/rust/commits/e63ec2e1402eaff949e5c53b8f6062b152010fcc" + } + ], + "sha": "8789e5392975203137765d7818fb23ad125782b3", + "url": "https://api.github.com/repos/rust-lang/rust/commits/8789e5392975203137765d7818fb23ad125782b3" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/11d96b59307b1702fffe871bfc2d0145d070881e/comments", + "commit": { + "author": { + "date": "2023-02-01T11:37:24Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-01T11:37:24Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107257 - inquisitivecrystal:ffi-attr, r=davidtwco\n\nStrengthen validation of FFI attributes\n\nPreviously, `codegen_attrs` validated the attributes `#[ffi_pure]`, `#[ffi_const]`, and `#[ffi_returns_twice]` to make sure that they were only used on foreign functions. However, this validation was insufficient in two ways:\n\n1. `codegen_attrs` only sees items for which code must be generated, so it was unable to raise errors when the attribute was incorrectly applied to macros and the like.\n2. the validation code only checked that the item with the attr was foreign, but not that it was a foreign function, allowing these attributes to be applied to foreign statics as well.\n\nThis PR moves the validation to `check_attr`, which sees all items. It additionally changes the validation to ensure that the attribute's target is `Target::ForeignFunction`, only allowing the attributes on foreign functions and not foreign statics. Because these attributes are unstable, there is no risk for backwards compatibility. The changes also ending up making the code much easier to read.\n\nThis PR is best reviewed commit by commit. Additionally, I was considering moving the tests to the `attribute` subdirectory, to get them out of the general UI directory. I could do that as part of this PR or a follow-up, as the reviewer prefers.\n\nCC: #58328, #58329", + "tree": { + "sha": "af26139253d2807f229208f8301714afc803c306", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/af26139253d2807f229208f8301714afc803c306" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/11d96b59307b1702fffe871bfc2d0145d070881e", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/11d96b59307b1702fffe871bfc2d0145d070881e", + "node_id": "C_kwDOAAsO6NoAKDExZDk2YjU5MzA3YjE3MDJmZmZlODcxYmZjMmQwMTQ1ZDA3MDg4MWU", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/3b639486c17e9144a9176382ecb2a0b801263935", + "sha": "3b639486c17e9144a9176382ecb2a0b801263935", + "url": "https://api.github.com/repos/rust-lang/rust/commits/3b639486c17e9144a9176382ecb2a0b801263935" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/bc23e9aa4c78066043be246a47627746341480dd", + "sha": "bc23e9aa4c78066043be246a47627746341480dd", + "url": "https://api.github.com/repos/rust-lang/rust/commits/bc23e9aa4c78066043be246a47627746341480dd" + } + ], + "sha": "11d96b59307b1702fffe871bfc2d0145d070881e", + "url": "https://api.github.com/repos/rust-lang/rust/commits/11d96b59307b1702fffe871bfc2d0145d070881e" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/3b639486c17e9144a9176382ecb2a0b801263935/comments", + "commit": { + "author": { + "date": "2023-02-01T07:47:29Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-01T07:47:29Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107546 - matthiaskrgr:rollup-9rgf2gx, r=matthiaskrgr\n\nRollup of 6 pull requests\n\nSuccessful merges:\n\n - #107389 (Fixing confusion between mod and remainder)\n - #107442 (improve panic message for slice windows and chunks)\n - #107470 (Small bootstrap improvements)\n - #107487 (Make the \"extra if in let...else block\" hint a suggestion)\n - #107499 (Do not depend on Generator trait when deducing closure signature)\n - #107533 (Extend `-Z print-type-sizes` to distinguish generator upvars+locals from \"normal\" fields.)\n\nFailed merges:\n\nr? `@ghost`\n`@rustbot` modify labels: rollup", + "tree": { + "sha": "7a062a4c43bf11d1fa11b1efdfd496d8a6f40d78", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/7a062a4c43bf11d1fa11b1efdfd496d8a6f40d78" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/3b639486c17e9144a9176382ecb2a0b801263935", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/3b639486c17e9144a9176382ecb2a0b801263935", + "node_id": "C_kwDOAAsO6NoAKDNiNjM5NDg2YzE3ZTkxNDRhOTE3NjM4MmVjYjJhMGI4MDEyNjM5MzU", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/0d32c8f2ce10710b6560dcb75f32f79c378410d0", + "sha": "0d32c8f2ce10710b6560dcb75f32f79c378410d0", + "url": "https://api.github.com/repos/rust-lang/rust/commits/0d32c8f2ce10710b6560dcb75f32f79c378410d0" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/f41f154dfbe2aa943e35a21c0e2a8de002443424", + "sha": "f41f154dfbe2aa943e35a21c0e2a8de002443424", + "url": "https://api.github.com/repos/rust-lang/rust/commits/f41f154dfbe2aa943e35a21c0e2a8de002443424" + } + ], + "sha": "3b639486c17e9144a9176382ecb2a0b801263935", + "url": "https://api.github.com/repos/rust-lang/rust/commits/3b639486c17e9144a9176382ecb2a0b801263935" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/0d32c8f2ce10710b6560dcb75f32f79c378410d0/comments", + "commit": { + "author": { + "date": "2023-02-01T04:53:29Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-01T04:53:29Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107541 - weihanglo:update-cargo, r=weihanglo\n\nUpdate cargo\n\n18 commits in 3c5af6bed9a1a243a693e8e22ee2486bd5b82a6c..e84a7928d93a31f284b497c214a2ece69b4d7719 2023-01-24 15:48:15 +0000 to 2023-01-31 22:18:09 +0000\n\n- chore: Add autolabel for `Command-*` labels (rust-lang/cargo#11664)\n- Update cross test instructions for aarch64-apple-darwin (rust-lang/cargo#11663)\n- Make cargo install report needed features (rust-lang/cargo#11647)\n- docs(contrib): Remove out-of-date process step (rust-lang/cargo#11662)\n- Do not error for `auth-required: true` without `-Z sparse-registry` (rust-lang/cargo#11661)\n- Warn on commits to non-default branches. (rust-lang/cargo#11655)\n- Avoid saving the same future_incompat warning multiple times (rust-lang/cargo#11648)\n- Mention current default value in `publish.timeout` docs (rust-lang/cargo#11652)\n- Make cargo aware of dwp files. (rust-lang/cargo#11572)\n- Reduce target info rustc query calls (rust-lang/cargo#11633)\n- Bump to 0.70.0; update changelog (rust-lang/cargo#11640)\n- Enable sparse protocol in CI (rust-lang/cargo#11632)\n- Fix split-debuginfo support detection (rust-lang/cargo#11347)\n- refactor(toml): Move `TomlWorkspaceDependency` out of `TomlDependency` (rust-lang/cargo#11565)\n- book: describe how the current resolver sometimes duplicates deps (rust-lang/cargo#11604)\n- `cargo add` check `[dependencies]` order without considering the dotted item (rust-lang/cargo#11612)\n- Link CoC to www.rust-lang.org/conduct.html (rust-lang/cargo#11622)\n- Add more labels to triagebot (rust-lang/cargo#11621)\n\nr? `@ghost`", + "tree": { + "sha": "9e08bab8c2e9b024e7ce120ed0c1fa7bbea9c463", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/9e08bab8c2e9b024e7ce120ed0c1fa7bbea9c463" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/0d32c8f2ce10710b6560dcb75f32f79c378410d0", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/0d32c8f2ce10710b6560dcb75f32f79c378410d0", + "node_id": "C_kwDOAAsO6NoAKDBkMzJjOGYyY2UxMDcxMGI2NTYwZGNiNzVmMzJmNzljMzc4NDEwZDA", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/ad8e1dc2863f63c35ef3ceef3064d0851a1d2582", + "sha": "ad8e1dc2863f63c35ef3ceef3064d0851a1d2582", + "url": "https://api.github.com/repos/rust-lang/rust/commits/ad8e1dc2863f63c35ef3ceef3064d0851a1d2582" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/bb2af4f28ca89b5088db433645f9e61f03c9ac2c", + "sha": "bb2af4f28ca89b5088db433645f9e61f03c9ac2c", + "url": "https://api.github.com/repos/rust-lang/rust/commits/bb2af4f28ca89b5088db433645f9e61f03c9ac2c" + } + ], + "sha": "0d32c8f2ce10710b6560dcb75f32f79c378410d0", + "url": "https://api.github.com/repos/rust-lang/rust/commits/0d32c8f2ce10710b6560dcb75f32f79c378410d0" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/ad8e1dc2863f63c35ef3ceef3064d0851a1d2582/comments", + "commit": { + "author": { + "date": "2023-02-01T01:15:02Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-02-01T01:15:02Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107536 - GuillaumeGomez:rollup-xv7dx2h, r=GuillaumeGomez\n\nRollup of 12 pull requests\n\nSuccessful merges:\n\n - #106898 (Include both md and yaml ICE ticket templates)\n - #107331 (Clean up eslint annotations and remove unused JS function)\n - #107348 (small refactor to new projection code)\n - #107354 (rustdoc: update Source Serif 4 from 4.004 to 4.005)\n - #107412 (avoid needless checks)\n - #107467 (Improve enum checks)\n - #107486 (Track bound types like bound regions)\n - #107491 (rustdoc: remove unused CSS from `.setting-check`)\n - #107508 (`Edition` micro refactor)\n - #107525 (PointeeInfo is advisory only)\n - #107527 (rustdoc: stop making unstable items transparent)\n - #107535 (Replace unwrap with ? in TcpListener doc)\n\nFailed merges:\n\nr? `@ghost`\n`@rustbot` modify labels: rollup", + "tree": { + "sha": "64d8db18dc8c8e118fd859c74061a34efbcae9d4", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/64d8db18dc8c8e118fd859c74061a34efbcae9d4" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/ad8e1dc2863f63c35ef3ceef3064d0851a1d2582", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/ad8e1dc2863f63c35ef3ceef3064d0851a1d2582", + "node_id": "C_kwDOAAsO6NoAKGFkOGUxZGMyODYzZjYzYzM1ZWYzY2VlZjMwNjRkMDg1MWExZDI1ODI", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/5b6ed253c42a69b93e7447fb0874a89ab6bc1cfb", + "sha": "5b6ed253c42a69b93e7447fb0874a89ab6bc1cfb", + "url": "https://api.github.com/repos/rust-lang/rust/commits/5b6ed253c42a69b93e7447fb0874a89ab6bc1cfb" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/adc3f8a44b943463577a5f8870da8fd18b749351", + "sha": "adc3f8a44b943463577a5f8870da8fd18b749351", + "url": "https://api.github.com/repos/rust-lang/rust/commits/adc3f8a44b943463577a5f8870da8fd18b749351" + } + ], + "sha": "ad8e1dc2863f63c35ef3ceef3064d0851a1d2582", + "url": "https://api.github.com/repos/rust-lang/rust/commits/ad8e1dc2863f63c35ef3ceef3064d0851a1d2582" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/5b6ed253c42a69b93e7447fb0874a89ab6bc1cfb/comments", + "commit": { + "author": { + "date": "2023-01-31T22:34:26Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-01-31T22:34:26Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #102513 - RalfJung:no-more-unaligned-reference, r=cjgillot,scottmcm\n\nmake unaligned_reference a hard error\n\nThe `unaligned_references` lint has been warn-by-default since Rust 1.53 (https://github.com/rust-lang/rust/pull/82525) and deny-by-default with mention in cargo future-incompat reports since Rust 1.62 (https://github.com/rust-lang/rust/pull/95372). Current nightly will become Rust 1.66, so (unless major surprises show up with crater) I think it is time we make this a hard error, and close this old soundness gap in the language.\n\nEDIT: Turns out this will only land for Rust 1.67, so there is another 6 weeks of time here for crates to adjust.\n\nFixes https://github.com/rust-lang/rust/issues/82523.", + "tree": { + "sha": "ba7e23c105713658431c3101d22977d8282e397f", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/ba7e23c105713658431c3101d22977d8282e397f" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/5b6ed253c42a69b93e7447fb0874a89ab6bc1cfb", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/5b6ed253c42a69b93e7447fb0874a89ab6bc1cfb", + "node_id": "C_kwDOAAsO6NoAKDViNmVkMjUzYzQyYTY5YjkzZTc0NDdmYjA4NzRhODlhYjZiYzFjZmI", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/dc1d9d50fba2f6a1ccab8748a0050cde38253f60", + "sha": "dc1d9d50fba2f6a1ccab8748a0050cde38253f60", + "url": "https://api.github.com/repos/rust-lang/rust/commits/dc1d9d50fba2f6a1ccab8748a0050cde38253f60" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/dfc4a7b2d02528f246e455f587605cce224bb99c", + "sha": "dfc4a7b2d02528f246e455f587605cce224bb99c", + "url": "https://api.github.com/repos/rust-lang/rust/commits/dfc4a7b2d02528f246e455f587605cce224bb99c" + } + ], + "sha": "5b6ed253c42a69b93e7447fb0874a89ab6bc1cfb", + "url": "https://api.github.com/repos/rust-lang/rust/commits/5b6ed253c42a69b93e7447fb0874a89ab6bc1cfb" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/dc1d9d50fba2f6a1ccab8748a0050cde38253f60/comments", + "commit": { + "author": { + "date": "2023-01-31T19:24:29Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-01-31T19:24:29Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107297 - Mark-Simulacrum:bump-bootstrap, r=pietroalbini\n\nBump bootstrap compiler to 1.68\n\nThis also changes our stage0.json to include the rustc component for the rustfmt pinned nightly toolchain, which is currently necessary due to rustfmt dynamically linking to that toolchain's librustc_driver and libstd.\n\nr? `@pietroalbini`", + "tree": { + "sha": "1497db582bb148e212d04fb4acc229d85aff2617", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/1497db582bb148e212d04fb4acc229d85aff2617" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/dc1d9d50fba2f6a1ccab8748a0050cde38253f60", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/dc1d9d50fba2f6a1ccab8748a0050cde38253f60", + "node_id": "C_kwDOAAsO6NoAKGRjMWQ5ZDUwZmJhMmY2YTFjY2FiODc0OGEwMDUwY2RlMzgyNTNmNjA", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/f361413cbf44ce2f144df59fc440cd484af4a56e", + "sha": "f361413cbf44ce2f144df59fc440cd484af4a56e", + "url": "https://api.github.com/repos/rust-lang/rust/commits/f361413cbf44ce2f144df59fc440cd484af4a56e" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/652f79e83543eab07c33840748cf5df37b42ac66", + "sha": "652f79e83543eab07c33840748cf5df37b42ac66", + "url": "https://api.github.com/repos/rust-lang/rust/commits/652f79e83543eab07c33840748cf5df37b42ac66" + } + ], + "sha": "dc1d9d50fba2f6a1ccab8748a0050cde38253f60", + "url": "https://api.github.com/repos/rust-lang/rust/commits/dc1d9d50fba2f6a1ccab8748a0050cde38253f60" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/f361413cbf44ce2f144df59fc440cd484af4a56e/comments", + "commit": { + "author": { + "date": "2023-01-31T13:53:40Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-01-31T13:53:40Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #106399 - estebank:type-err-span-label, r=nagisa\n\nModify primary span label for E0308\n\nLooking at the reactions to https://hachyderm.io/`@ekuber/109622160673605438,` a lot of people seem to have trouble understanding the current output, where the primary span label on type errors talks about the specific types that diverged, but these can be deeply nested type parameters. Because of that we could see \"expected i32, found u32\" in the label while the note said \"expected Vec, found Vec\". This understandably confuses people. I believe that once people learn to read these errors it starts to make more sense, but this PR changes the output to be more in line with what people might expect, without sacrificing terseness.\n\nFix #68220.", + "tree": { + "sha": "cecf91d94ee20df2d6bec7c88796b90fa34f9887", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/cecf91d94ee20df2d6bec7c88796b90fa34f9887" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/f361413cbf44ce2f144df59fc440cd484af4a56e", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/f361413cbf44ce2f144df59fc440cd484af4a56e", + "node_id": "C_kwDOAAsO6NoAKGYzNjE0MTNjYmY0NGNlMmYxNDRkZjU5ZmM0NDBjZDQ4NGFmNGE1NmU", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/a64ef7d07d0411315be85a646586cb85eeb9c136", + "sha": "a64ef7d07d0411315be85a646586cb85eeb9c136", + "url": "https://api.github.com/repos/rust-lang/rust/commits/a64ef7d07d0411315be85a646586cb85eeb9c136" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/449dfc64f0792f2320ef68bc08f238281199f53d", + "sha": "449dfc64f0792f2320ef68bc08f238281199f53d", + "url": "https://api.github.com/repos/rust-lang/rust/commits/449dfc64f0792f2320ef68bc08f238281199f53d" + } + ], + "sha": "f361413cbf44ce2f144df59fc440cd484af4a56e", + "url": "https://api.github.com/repos/rust-lang/rust/commits/f361413cbf44ce2f144df59fc440cd484af4a56e" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/a64ef7d07d0411315be85a646586cb85eeb9c136/comments", + "commit": { + "author": { + "date": "2023-01-31T10:20:58Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-01-31T10:20:58Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #100754 - davidtwco:translation-incremental, r=compiler-errors\n\nincremental: migrate diagnostics\n\n- Apply the diagnostic migration lints to more functions on `Session`, namely: `span_warn`, `span_warn_with_code`, `warn` `note_without_error`, `span_note_without_error`, `struct_note_without_error`.\n- Add impls of `IntoDiagnosticArg` for `std::io::Error`, `std::path::Path` and `std::path::PathBuf`.\n- Migrate the `rustc_incremental` crate's diagnostics to translatable diagnostic structs.\n\nr? `@compiler-errors`\ncc #100717", + "tree": { + "sha": "e4b006e2f97095541ee5ff8b1beab16675e5eb86", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/e4b006e2f97095541ee5ff8b1beab16675e5eb86" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/a64ef7d07d0411315be85a646586cb85eeb9c136", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/a64ef7d07d0411315be85a646586cb85eeb9c136", + "node_id": "C_kwDOAAsO6NoAKGE2NGVmN2QwN2QwNDExMzE1YmU4NWE2NDY1ODZjYjg1ZWViOWMxMzY", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/7c4a9a971ca6962533bed01ffbd0c1f6b5250abc", + "sha": "7c4a9a971ca6962533bed01ffbd0c1f6b5250abc", + "url": "https://api.github.com/repos/rust-lang/rust/commits/7c4a9a971ca6962533bed01ffbd0c1f6b5250abc" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/2ff46641a92c27a32db3e0dc94ae86295e6c3277", + "sha": "2ff46641a92c27a32db3e0dc94ae86295e6c3277", + "url": "https://api.github.com/repos/rust-lang/rust/commits/2ff46641a92c27a32db3e0dc94ae86295e6c3277" + } + ], + "sha": "a64ef7d07d0411315be85a646586cb85eeb9c136", + "url": "https://api.github.com/repos/rust-lang/rust/commits/a64ef7d07d0411315be85a646586cb85eeb9c136" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/7c4a9a971ca6962533bed01ffbd0c1f6b5250abc/comments", + "commit": { + "author": { + "date": "2023-01-31T06:25:30Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2023-01-31T06:25:30Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #107498 - JohnTitor:rollup-2i6g4uk, r=JohnTitor\n\nRollup of 8 pull requests\n\nSuccessful merges:\n\n - #107245 (Implement unsizing in the new trait solver)\n - #107445 (Remove `GenFuture` from core)\n - #107473 (Update books)\n - #107476 (rustdoc: remove unnecessary wrapper `div.item-decl` from HTML)\n - #107477 (Migrate last part of CSS themes to CSS variables)\n - #107479 (Use `ObligationCtxt::new_in_snapshot` in `satisfied_from_param_env`)\n - #107482 (rustdoc: remove meta keywords from HTML)\n - #107494 (fix link in std::path::Path::display())\n\nFailed merges:\n\nr? `@ghost`\n`@rustbot` modify labels: rollup", + "tree": { + "sha": "904e6bf143781822be126e176f256545da3767dd", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/904e6bf143781822be126e176f256545da3767dd" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/7c4a9a971ca6962533bed01ffbd0c1f6b5250abc", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/7c4a9a971ca6962533bed01ffbd0c1f6b5250abc", + "node_id": "C_kwDOAAsO6NoAKDdjNGE5YTk3MWNhNjk2MjUzM2JlZDAxZmZiZDBjMWY2YjUyNTBhYmM", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/dc3e59cb3fe05ebd752d3a2269f501c00327be22", + "sha": "dc3e59cb3fe05ebd752d3a2269f501c00327be22", + "url": "https://api.github.com/repos/rust-lang/rust/commits/dc3e59cb3fe05ebd752d3a2269f501c00327be22" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/150340bafdcd48becbe612a0d4d5631efe23621c", + "sha": "150340bafdcd48becbe612a0d4d5631efe23621c", + "url": "https://api.github.com/repos/rust-lang/rust/commits/150340bafdcd48becbe612a0d4d5631efe23621c" + } + ], + "sha": "7c4a9a971ca6962533bed01ffbd0c1f6b5250abc", + "url": "https://api.github.com/repos/rust-lang/rust/commits/7c4a9a971ca6962533bed01ffbd0c1f6b5250abc" + } + ] +} diff --git a/tests/github_client/create_commit/00-GET-repos_ehuss_rust.json b/tests/github_client/create_commit/00-GET-repos_ehuss_rust.json new file mode 100644 index 00000000..2e719ca7 --- /dev/null +++ b/tests/github_client/create_commit/00-GET-repos_ehuss_rust.json @@ -0,0 +1,365 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/ehuss/rust", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/rust/branches{/branch}", + "clone_url": "https://github.com/ehuss/rust.git", + "collaborators_url": "https://api.github.com/repos/ehuss/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/rust/contributors", + "created_at": "2018-01-14T20:35:48Z", + "default_branch": "master", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/rust/deployments", + "description": "A safe, concurrent, practical language.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/rust/downloads", + "events_url": "https://api.github.com/repos/ehuss/rust/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/ehuss/rust/forks", + "full_name": "ehuss/rust", + "git_commits_url": "https://api.github.com/repos/ehuss/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/rust/git/tags{/sha}", + "git_url": "git://github.com/ehuss/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": false, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/ehuss/rust/hooks", + "html_url": "https://github.com/ehuss/rust", + "id": 117464625, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/ehuss/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/rust/merges", + "milestones_url": "https://api.github.com/repos/ehuss/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "network_count": 10326, + "node_id": "MDEwOlJlcG9zaXRvcnkxMTc0NjQ2MjU=", + "notifications_url": "https://api.github.com/repos/ehuss/rust/notifications{?since,all,participating}", + "open_issues": 0, + "open_issues_count": 0, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "parent": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10326, + "forks_count": 10326, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9513, + "open_issues_count": 9513, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T18:16:26Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066392, + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77401, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T17:54:34Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "visibility": "public", + "watchers": 77401, + "watchers_count": 77401, + "web_commit_signoff_required": false + }, + "permissions": { + "admin": true, + "maintain": true, + "pull": true, + "push": true, + "triage": true + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/rust/pulls{/number}", + "pushed_at": "2023-02-05T19:01:28Z", + "releases_url": "https://api.github.com/repos/ehuss/rust/releases{/id}", + "security_and_analysis": { + "secret_scanning": { + "status": "disabled" + }, + "secret_scanning_push_protection": { + "status": "disabled" + } + }, + "size": 1054343, + "source": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10326, + "forks_count": 10326, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9513, + "open_issues_count": 9513, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T18:16:26Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066392, + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77401, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T17:54:34Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "visibility": "public", + "watchers": 77401, + "watchers_count": 77401, + "web_commit_signoff_required": false + }, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/rust.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/rust/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/rust/statuses/{sha}", + "subscribers_count": 0, + "subscribers_url": "https://api.github.com/repos/ehuss/rust/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/rust/subscription", + "svn_url": "https://github.com/ehuss/rust", + "tags_url": "https://api.github.com/repos/ehuss/rust/tags", + "teams_url": "https://api.github.com/repos/ehuss/rust/teams", + "temp_clone_token": "", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/rust/git/trees{/sha}", + "updated_at": "2021-11-03T23:44:04Z", + "url": "https://api.github.com/repos/ehuss/rust", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + } +} diff --git a/tests/github_client/create_commit/01-POST-repos_ehuss_rust_git_commits.json b/tests/github_client/create_commit/01-POST-repos_ehuss_rust_git_commits.json new file mode 100644 index 00000000..08cc813f --- /dev/null +++ b/tests/github_client/create_commit/01-POST-repos_ehuss_rust_git_commits.json @@ -0,0 +1,42 @@ +{ + "kind": "Request", + "method": "POST", + "path": "/repos/ehuss/rust/git/commits", + "query": null, + "request_body": "{\"message\":\"test reference commit\",\"parents\":[\"319b88c463fe6f51bb6badbbd3bb97252a60f3a5\"],\"tree\":\"45aae523b087e418f2778d4557489de38fede6a3\"}", + "response_code": 201, + "response_body": { + "author": { + "date": "2023-02-05T19:08:57Z", + "email": "eric@huss.org", + "name": "Eric Huss" + }, + "committer": { + "date": "2023-02-05T19:08:57Z", + "email": "eric@huss.org", + "name": "Eric Huss" + }, + "html_url": "https://github.com/ehuss/rust/commit/88a426017fa4635ba42203c3b1d1c19f6a028184", + "message": "test reference commit", + "node_id": "C_kwDOBwBeMdoAKDg4YTQyNjAxN2ZhNDYzNWJhNDIyMDNjM2IxZDFjMTlmNmEwMjgxODQ", + "parents": [ + { + "html_url": "https://github.com/ehuss/rust/commit/319b88c463fe6f51bb6badbbd3bb97252a60f3a5", + "sha": "319b88c463fe6f51bb6badbbd3bb97252a60f3a5", + "url": "https://api.github.com/repos/ehuss/rust/git/commits/319b88c463fe6f51bb6badbbd3bb97252a60f3a5" + } + ], + "sha": "88a426017fa4635ba42203c3b1d1c19f6a028184", + "tree": { + "sha": "45aae523b087e418f2778d4557489de38fede6a3", + "url": "https://api.github.com/repos/ehuss/rust/git/trees/45aae523b087e418f2778d4557489de38fede6a3" + }, + "url": "https://api.github.com/repos/ehuss/rust/git/commits/88a426017fa4635ba42203c3b1d1c19f6a028184", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + } +} diff --git a/tests/github_client/get_issues_no_search/00-GET-repos_rust-lang_rust.json b/tests/github_client/get_issues_no_search/00-GET-repos_rust-lang_rust.json new file mode 100644 index 00000000..3589a6e8 --- /dev/null +++ b/tests/github_client/get_issues_no_search/00-GET-repos_rust-lang_rust.json @@ -0,0 +1,160 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": false, + "allow_squash_merge": false, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "delete_branch_on_merge": true, + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10326, + "forks_count": 10326, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "network_count": 10326, + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9513, + "open_issues_count": 9513, + "organization": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "permissions": { + "admin": false, + "maintain": false, + "pull": true, + "push": true, + "triage": true + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T18:16:26Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066392, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77402, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_count": 1487, + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "temp_clone_token": "", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T19:09:47Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 77402, + "watchers_count": 77402, + "web_commit_signoff_required": false + } +} diff --git a/tests/github_client/get_issues_no_search/01-GET-repos_rust-lang_rust_issues.json b/tests/github_client/get_issues_no_search/01-GET-repos_rust-lang_rust_issues.json new file mode 100644 index 00000000..d0a8d7d1 --- /dev/null +++ b/tests/github_client/get_issues_no_search/01-GET-repos_rust-lang_rust_issues.json @@ -0,0 +1,431 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust/issues", + "query": "labels=A-coherence&filter=all&sort=created&direction=asc&per_page=100", + "request_body": "", + "response_code": 200, + "response_body": [ + { + "active_lock_reason": null, + "assignee": { + "avatar_url": "https://avatars.githubusercontent.com/u/16256974?v=4", + "events_url": "https://api.github.com/users/atsuzaki/events{/privacy}", + "followers_url": "https://api.github.com/users/atsuzaki/followers", + "following_url": "https://api.github.com/users/atsuzaki/following{/other_user}", + "gists_url": "https://api.github.com/users/atsuzaki/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/atsuzaki", + "id": 16256974, + "login": "atsuzaki", + "node_id": "MDQ6VXNlcjE2MjU2OTc0", + "organizations_url": "https://api.github.com/users/atsuzaki/orgs", + "received_events_url": "https://api.github.com/users/atsuzaki/received_events", + "repos_url": "https://api.github.com/users/atsuzaki/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/atsuzaki/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/atsuzaki/subscriptions", + "type": "User", + "url": "https://api.github.com/users/atsuzaki" + }, + "assignees": [ + { + "avatar_url": "https://avatars.githubusercontent.com/u/16256974?v=4", + "events_url": "https://api.github.com/users/atsuzaki/events{/privacy}", + "followers_url": "https://api.github.com/users/atsuzaki/followers", + "following_url": "https://api.github.com/users/atsuzaki/following{/other_user}", + "gists_url": "https://api.github.com/users/atsuzaki/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/atsuzaki", + "id": 16256974, + "login": "atsuzaki", + "node_id": "MDQ6VXNlcjE2MjU2OTc0", + "organizations_url": "https://api.github.com/users/atsuzaki/orgs", + "received_events_url": "https://api.github.com/users/atsuzaki/received_events", + "repos_url": "https://api.github.com/users/atsuzaki/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/atsuzaki/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/atsuzaki/subscriptions", + "type": "User", + "url": "https://api.github.com/users/atsuzaki" + } + ], + "author_association": "MEMBER", + "body": "We consider projections to be foreign types during orphan check\n\nhttps://github.com/rust-lang/rust/blob/ceeb5ade201e4181c6d5df2ba96ae5fb2193aadc/compiler/rustc_trait_selection/src/traits/coherence.rs#L731\n\nbut do not consider them to be parameters when checking for uncovered types https://github.com/rust-lang/rust/blob/ceeb5ade201e4181c6d5df2ba96ae5fb2193aadc/compiler/rustc_trait_selection/src/traits/coherence.rs#L621\n\nThis is more obvious after #99552\n\nthis means that the following impl passes the orphan check even though it shouldn't\n```rust\n// crate a\npub trait Foreign {\n type Assoc;\n}\n\n// crate b\nuse a::Foreign;\n\ntrait Id {\n type Assoc;\n}\n\nimpl Id for T {\n type Assoc = T;\n}\n\npub struct B;\nimpl Foreign for ::Assoc {\n type Assoc = usize;\n}\n```\nThe impl in `b` overlaps with an impl `impl Foreign for LocalTy` in another crate `c` which passes the orphan check.\n\nWhile I wasn't able to cause runtime UB with this, I was able to get an ICE during `codegen_fulfill_obligation`: https://github.com/lcnr/orphan-check-ub\n\ncc @rust-lang/types \n\n\n\n\n\n\n\n\n", + "closed_at": null, + "comments": 5, + "comments_url": "https://api.github.com/repos/rust-lang/rust/issues/99554/comments", + "created_at": "2022-07-21T10:56:00Z", + "events_url": "https://api.github.com/repos/rust-lang/rust/issues/99554/events", + "html_url": "https://github.com/rust-lang/rust/issues/99554", + "id": 1313070635, + "labels": [ + { + "color": "f7e101", + "default": false, + "description": "Area: Trait system", + "id": 13836860, + "name": "A-traits", + "node_id": "MDU6TGFiZWwxMzgzNjg2MA==", + "url": "https://api.github.com/repos/rust-lang/rust/labels/A-traits" + }, + { + "color": "02E10C", + "default": false, + "description": "Call for participation: This issue has a mentor. Use RustcContributor::new on Zulip for discussion.", + "id": 67766349, + "name": "E-mentor", + "node_id": "MDU6TGFiZWw2Nzc2NjM0OQ==", + "url": "https://api.github.com/repos/rust-lang/rust/labels/E-mentor" + }, + { + "color": "f7e101", + "default": false, + "description": "Area: Associated items such as associated types and consts.", + "id": 149689562, + "name": "A-associated-items", + "node_id": "MDU6TGFiZWwxNDk2ODk1NjI=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/A-associated-items" + }, + { + "color": "eb6420", + "default": false, + "description": "High priority", + "id": 203429200, + "name": "P-high", + "node_id": "MDU6TGFiZWwyMDM0MjkyMDA=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/P-high" + }, + { + "color": "e11d21", + "default": false, + "description": "Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness", + "id": 267612997, + "name": "I-unsound", + "node_id": "MDU6TGFiZWwyNjc2MTI5OTc=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/I-unsound" + }, + { + "color": "02e10c", + "default": false, + "description": "Call for participation: Experience needed to fix: Medium / intermediate", + "id": 419557634, + "name": "E-medium", + "node_id": "MDU6TGFiZWw0MTk1NTc2MzQ=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/E-medium" + }, + { + "color": "f5f1fd", + "default": false, + "description": "Category: This is a bug.", + "id": 650731663, + "name": "C-bug", + "node_id": "MDU6TGFiZWw2NTA3MzE2NjM=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/C-bug" + }, + { + "color": "bfd4f2", + "default": false, + "description": "Relevant to the types team, which will review and decide on the PR/issue.", + "id": 4172483496, + "name": "T-types", + "node_id": "LA_kwDOAAsO6M74swuo", + "url": "https://api.github.com/repos/rust-lang/rust/labels/T-types" + }, + { + "color": "f7e101", + "default": false, + "description": "Area: Coherence", + "id": 4917350639, + "name": "A-coherence", + "node_id": "LA_kwDOAAsO6M8AAAABJRjQ7w", + "url": "https://api.github.com/repos/rust-lang/rust/labels/A-coherence" + } + ], + "labels_url": "https://api.github.com/repos/rust-lang/rust/issues/99554/labels{/name}", + "locked": false, + "milestone": null, + "node_id": "I_kwDOAAsO6M5OQ94r", + "number": 99554, + "performed_via_github_app": null, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/rust-lang/rust/issues/99554/reactions" + }, + "repository_url": "https://api.github.com/repos/rust-lang/rust", + "state": "open", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/rust-lang/rust/issues/99554/timeline", + "title": "orphan check incorrectly handles projections", + "updated_at": "2023-01-27T17:08:45Z", + "url": "https://api.github.com/repos/rust-lang/rust/issues/99554", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/29864074?v=4", + "events_url": "https://api.github.com/users/lcnr/events{/privacy}", + "followers_url": "https://api.github.com/users/lcnr/followers", + "following_url": "https://api.github.com/users/lcnr/following{/other_user}", + "gists_url": "https://api.github.com/users/lcnr/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/lcnr", + "id": 29864074, + "login": "lcnr", + "node_id": "MDQ6VXNlcjI5ODY0MDc0", + "organizations_url": "https://api.github.com/users/lcnr/orgs", + "received_events_url": "https://api.github.com/users/lcnr/received_events", + "repos_url": "https://api.github.com/users/lcnr/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/lcnr/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/lcnr/subscriptions", + "type": "User", + "url": "https://api.github.com/users/lcnr" + } + }, + { + "active_lock_reason": null, + "assignee": null, + "assignees": [], + "author_association": "MEMBER", + "body": "which is unsound during coherence, as coherence requires completeness\r\n```rust\r\n#![feature(specialization)]\r\n\r\ntrait Default {\r\n type Id;\r\n}\r\n\r\nimpl Default for T {\r\n default type Id = T;\r\n}\r\n\r\ntrait Overlap {\r\n type Assoc;\r\n}\r\n\r\nimpl Overlap for u32 {\r\n type Assoc = usize;\r\n}\r\n\r\nimpl Overlap for ::Id {\r\n type Assoc = Box;\r\n}\r\n```\r\n\r\nhttps://github.com/rust-lang/rust/blob/03770f0e2b60c02db8fcf52fed5fb36aac70cedc/compiler/rustc_trait_selection/src/traits/project.rs#L1526", + "closed_at": null, + "comments": 0, + "comments_url": "https://api.github.com/repos/rust-lang/rust/issues/105782/comments", + "created_at": "2022-12-16T15:11:15Z", + "events_url": "https://api.github.com/repos/rust-lang/rust/issues/105782/events", + "html_url": "https://github.com/rust-lang/rust/issues/105782", + "id": 1500394507, + "labels": [ + { + "color": "f7e101", + "default": false, + "description": "Area: Trait system", + "id": 13836860, + "name": "A-traits", + "node_id": "MDU6TGFiZWwxMzgzNjg2MA==", + "url": "https://api.github.com/repos/rust-lang/rust/labels/A-traits" + }, + { + "color": "e11d21", + "default": false, + "description": "Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness", + "id": 267612997, + "name": "I-unsound", + "node_id": "MDU6TGFiZWwyNjc2MTI5OTc=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/I-unsound" + }, + { + "color": "f7e101", + "default": false, + "description": "Area: Trait impl specialization", + "id": 347795552, + "name": "A-specialization", + "node_id": "MDU6TGFiZWwzNDc3OTU1NTI=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/A-specialization" + }, + { + "color": "f5f1fd", + "default": false, + "description": "Category: This is a bug.", + "id": 650731663, + "name": "C-bug", + "node_id": "MDU6TGFiZWw2NTA3MzE2NjM=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/C-bug" + }, + { + "color": "76dcde", + "default": false, + "description": "This issue requires a nightly compiler in some way.", + "id": 1472563007, + "name": "requires-nightly", + "node_id": "MDU6TGFiZWwxNDcyNTYzMDA3", + "url": "https://api.github.com/repos/rust-lang/rust/labels/requires-nightly" + }, + { + "color": "f9c0cc", + "default": false, + "description": "`#![feature(specialization)]`", + "id": 1472579062, + "name": "F-specialization", + "node_id": "MDU6TGFiZWwxNDcyNTc5MDYy", + "url": "https://api.github.com/repos/rust-lang/rust/labels/F-specialization" + }, + { + "color": "f7e101", + "default": false, + "description": "Area: Coherence", + "id": 4917350639, + "name": "A-coherence", + "node_id": "LA_kwDOAAsO6M8AAAABJRjQ7w", + "url": "https://api.github.com/repos/rust-lang/rust/labels/A-coherence" + } + ], + "labels_url": "https://api.github.com/repos/rust-lang/rust/issues/105782/labels{/name}", + "locked": false, + "milestone": null, + "node_id": "I_kwDOAAsO6M5ZbjQL", + "number": 105782, + "performed_via_github_app": null, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/rust-lang/rust/issues/105782/reactions" + }, + "repository_url": "https://api.github.com/repos/rust-lang/rust", + "state": "open", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/rust-lang/rust/issues/105782/timeline", + "title": "specialization: default items completely drop candidates instead of ambiguity", + "updated_at": "2022-12-16T16:17:41Z", + "url": "https://api.github.com/repos/rust-lang/rust/issues/105782", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/29864074?v=4", + "events_url": "https://api.github.com/users/lcnr/events{/privacy}", + "followers_url": "https://api.github.com/users/lcnr/followers", + "following_url": "https://api.github.com/users/lcnr/following{/other_user}", + "gists_url": "https://api.github.com/users/lcnr/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/lcnr", + "id": 29864074, + "login": "lcnr", + "node_id": "MDQ6VXNlcjI5ODY0MDc0", + "organizations_url": "https://api.github.com/users/lcnr/orgs", + "received_events_url": "https://api.github.com/users/lcnr/received_events", + "repos_url": "https://api.github.com/users/lcnr/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/lcnr/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/lcnr/subscriptions", + "type": "User", + "url": "https://api.github.com/users/lcnr" + } + }, + { + "active_lock_reason": null, + "assignee": null, + "assignees": [], + "author_association": "MEMBER", + "body": "```rust\r\n// Using the higher ranked projection hack to prevent us from replacing the projection\r\n// with an inference variable.\r\ntrait ToUnit<'a> {\r\n type Unit;\r\n}\r\n\r\nstruct LocalTy;\r\nimpl<'a> ToUnit<'a> for *const LocalTy {\r\n type Unit = ();\r\n}\r\n\r\nimpl<'a, T: Copy + ?Sized> ToUnit<'a> for *const T {\r\n type Unit = ();\r\n}\r\n\r\ntrait Overlap {\r\n type Assoc;\r\n}\r\n\r\ntype Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit;\r\n\r\nimpl Overlap for T {\r\n type Assoc = usize;\r\n}\r\n\r\nimpl Overlap fn(&'a (), Assoc<'a, T>)> for T\r\nwhere\r\n for<'a> *const T: ToUnit<'a>,\r\n{\r\n type Assoc = Box;\r\n}\r\n\r\nfn foo, U>(x: T::Assoc) -> T::Assoc {\r\n x\r\n}\r\n\r\nfn main() {\r\n foo:: fn(&'a (), ()), for<'a> fn(&'a (), ())>(3usize);\r\n}\r\n```\r\n\r\n`for<'a> fn(&'a (), ())>: Overlap fn(&'a (), ())>>` can be satisfied using both impls, ignoring a deficiency of the current normalization routine which means that right now the second impl pretty much never applies.\r\n\r\nCurrently inference constraints from equating the self type are not used to normalize the trait argument so we fail when equating `()` with `Assoc<'a, for<'a> fn(&'a (), ())>` even those these two are the same type. This will change once deferred projection equality is implemented.\r\n\r\n## why this currently passes coherence\r\n\r\nCoherence does a pairwise check for all relevant impls. It starts by instantiating the impl parameters with inference vars and equating the impl headers. When we do that with `Overlap for T` and `Overlap fn(&'a (), Assoc<'a, T>)> for T` we have:\r\n\r\n- `eq(?0: Overflap, ?1: Overlap fn(&'a (), <*const ?1 as ToUnit<'a>>::Unit)>)`\r\n - `eq(?0, ?1)` constrains `?1` to be equal to `?0`\r\n - `eq(?0, for<'a> fn(&'a (), <*const ?0 as ToUnit<'a>>::Unit)>)`: this now fails the occurs check\r\n\r\nThe occurs check is necessary to prevent ourselves from creating infinitely large types, e.g. `?0 = Vec`. But it does mean that coherence considers these two impls to be disjoint. Because the inference var only occurs inside of a projection, there's a way to equate these two types without resulting in an infinitely large type by normalizing the projection.", + "closed_at": null, + "comments": 1, + "comments_url": "https://api.github.com/repos/rust-lang/rust/issues/105787/comments", + "created_at": "2022-12-16T16:16:11Z", + "events_url": "https://api.github.com/repos/rust-lang/rust/issues/105787/events", + "html_url": "https://github.com/rust-lang/rust/issues/105787", + "id": 1500501670, + "labels": [ + { + "color": "f7e101", + "default": false, + "description": "Area: Trait system", + "id": 13836860, + "name": "A-traits", + "node_id": "MDU6TGFiZWwxMzgzNjg2MA==", + "url": "https://api.github.com/repos/rust-lang/rust/labels/A-traits" + }, + { + "color": "eb6420", + "default": false, + "description": "Medium priority", + "id": 60344715, + "name": "P-medium", + "node_id": "MDU6TGFiZWw2MDM0NDcxNQ==", + "url": "https://api.github.com/repos/rust-lang/rust/labels/P-medium" + }, + { + "color": "e11d21", + "default": false, + "description": "Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness", + "id": 267612997, + "name": "I-unsound", + "node_id": "MDU6TGFiZWwyNjc2MTI5OTc=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/I-unsound" + }, + { + "color": "f5f1fd", + "default": false, + "description": "Category: This is a bug.", + "id": 650731663, + "name": "C-bug", + "node_id": "MDU6TGFiZWw2NTA3MzE2NjM=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/C-bug" + }, + { + "color": "bfd4f2", + "default": false, + "description": "Relevant to the types team, which will review and decide on the PR/issue.", + "id": 4172483496, + "name": "T-types", + "node_id": "LA_kwDOAAsO6M74swuo", + "url": "https://api.github.com/repos/rust-lang/rust/labels/T-types" + }, + { + "color": "f7e101", + "default": false, + "description": "Area: Coherence", + "id": 4917350639, + "name": "A-coherence", + "node_id": "LA_kwDOAAsO6M8AAAABJRjQ7w", + "url": "https://api.github.com/repos/rust-lang/rust/labels/A-coherence" + } + ], + "labels_url": "https://api.github.com/repos/rust-lang/rust/issues/105787/labels{/name}", + "locked": false, + "milestone": null, + "node_id": "I_kwDOAAsO6M5Zb9am", + "number": 105787, + "performed_via_github_app": null, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/rust-lang/rust/issues/105787/reactions" + }, + "repository_url": "https://api.github.com/repos/rust-lang/rust", + "state": "open", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/rust-lang/rust/issues/105787/timeline", + "title": "occurs check with projections results in error, not ambiguity", + "updated_at": "2022-12-17T05:07:04Z", + "url": "https://api.github.com/repos/rust-lang/rust/issues/105787", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/29864074?v=4", + "events_url": "https://api.github.com/users/lcnr/events{/privacy}", + "followers_url": "https://api.github.com/users/lcnr/followers", + "following_url": "https://api.github.com/users/lcnr/following{/other_user}", + "gists_url": "https://api.github.com/users/lcnr/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/lcnr", + "id": 29864074, + "login": "lcnr", + "node_id": "MDQ6VXNlcjI5ODY0MDc0", + "organizations_url": "https://api.github.com/users/lcnr/orgs", + "received_events_url": "https://api.github.com/users/lcnr/received_events", + "repos_url": "https://api.github.com/users/lcnr/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/lcnr/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/lcnr/subscriptions", + "type": "User", + "url": "https://api.github.com/users/lcnr" + } + } + ] +} diff --git a/tests/github_client/get_issues_with_search/00-GET-repos_rust-lang_rust.json b/tests/github_client/get_issues_with_search/00-GET-repos_rust-lang_rust.json new file mode 100644 index 00000000..fd9dcba7 --- /dev/null +++ b/tests/github_client/get_issues_with_search/00-GET-repos_rust-lang_rust.json @@ -0,0 +1,160 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": false, + "allow_squash_merge": false, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "delete_branch_on_merge": true, + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10327, + "forks_count": 10327, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "network_count": 10327, + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9516, + "open_issues_count": 9516, + "organization": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "permissions": { + "admin": false, + "maintain": false, + "pull": true, + "push": true, + "triage": true + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T21:22:12Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066392, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77405, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_count": 1487, + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "temp_clone_token": "", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T21:23:12Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 77405, + "watchers_count": 77405, + "web_commit_signoff_required": false + } +} diff --git a/tests/github_client/get_issues_with_search/01-GET-search_issues.json b/tests/github_client/get_issues_with_search/01-GET-search_issues.json new file mode 100644 index 00000000..cbc12b0e --- /dev/null +++ b/tests/github_client/get_issues_with_search/01-GET-search_issues.json @@ -0,0 +1,614 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/search/issues", + "query": "q=state:closed+is:pull-request+label:beta-nominated+label:beta-accepted+repo:rust-lang/rust&sort=created&order=asc&per_page=100&page=1", + "request_body": "", + "response_code": 200, + "response_body": { + "incomplete_results": false, + "items": [ + { + "active_lock_reason": null, + "assignee": { + "avatar_url": "https://avatars.githubusercontent.com/u/5047365?v=4", + "events_url": "https://api.github.com/users/Mark-Simulacrum/events{/privacy}", + "followers_url": "https://api.github.com/users/Mark-Simulacrum/followers", + "following_url": "https://api.github.com/users/Mark-Simulacrum/following{/other_user}", + "gists_url": "https://api.github.com/users/Mark-Simulacrum/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/Mark-Simulacrum", + "id": 5047365, + "login": "Mark-Simulacrum", + "node_id": "MDQ6VXNlcjUwNDczNjU=", + "organizations_url": "https://api.github.com/users/Mark-Simulacrum/orgs", + "received_events_url": "https://api.github.com/users/Mark-Simulacrum/received_events", + "repos_url": "https://api.github.com/users/Mark-Simulacrum/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/Mark-Simulacrum/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Mark-Simulacrum/subscriptions", + "type": "User", + "url": "https://api.github.com/users/Mark-Simulacrum" + }, + "assignees": [ + { + "avatar_url": "https://avatars.githubusercontent.com/u/5047365?v=4", + "events_url": "https://api.github.com/users/Mark-Simulacrum/events{/privacy}", + "followers_url": "https://api.github.com/users/Mark-Simulacrum/followers", + "following_url": "https://api.github.com/users/Mark-Simulacrum/following{/other_user}", + "gists_url": "https://api.github.com/users/Mark-Simulacrum/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/Mark-Simulacrum", + "id": 5047365, + "login": "Mark-Simulacrum", + "node_id": "MDQ6VXNlcjUwNDczNjU=", + "organizations_url": "https://api.github.com/users/Mark-Simulacrum/orgs", + "received_events_url": "https://api.github.com/users/Mark-Simulacrum/received_events", + "repos_url": "https://api.github.com/users/Mark-Simulacrum/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/Mark-Simulacrum/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Mark-Simulacrum/subscriptions", + "type": "User", + "url": "https://api.github.com/users/Mark-Simulacrum" + } + ], + "author_association": "MEMBER", + "body": "They were missing after recent move from src/test to tests.\r\n\r\ncc @albertlarsan68\r\n\r\nFixes #107081", + "closed_at": "2023-01-26T03:10:34Z", + "comments": 5, + "comments_url": "https://api.github.com/repos/rust-lang/rust/issues/107239/comments", + "created_at": "2023-01-23T20:54:12Z", + "draft": false, + "events_url": "https://api.github.com/repos/rust-lang/rust/issues/107239/events", + "html_url": "https://github.com/rust-lang/rust/pull/107239", + "id": 1553798773, + "labels": [ + { + "color": "1e76d9", + "default": false, + "description": "Nominated for backporting to the compiler in the beta channel.", + "id": 201991156, + "name": "beta-nominated", + "node_id": "MDU6TGFiZWwyMDE5OTExNTY=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/beta-nominated" + }, + { + "color": "1e76d9", + "default": false, + "description": "Accepted for backporting to the compiler in the beta channel.", + "id": 203428830, + "name": "beta-accepted", + "node_id": "MDU6TGFiZWwyMDM0Mjg4MzA=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/beta-accepted" + }, + { + "color": "bfd4f2", + "default": false, + "description": "Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap)", + "id": 325438536, + "name": "T-bootstrap", + "node_id": "MDU6TGFiZWwzMjU0Mzg1MzY=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/T-bootstrap" + }, + { + "color": "d3dddd", + "default": false, + "description": "Status: Waiting on bors to run and complete tests. Bors will change the label on completion.", + "id": 583437191, + "name": "S-waiting-on-bors", + "node_id": "MDU6TGFiZWw1ODM0MzcxOTE=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/S-waiting-on-bors" + }, + { + "color": "bfd4f2", + "default": false, + "description": "Relevant to the infrastructure team, which will review and decide on the PR/issue.", + "id": 593503757, + "name": "T-infra", + "node_id": "MDU6TGFiZWw1OTM1MDM3NTc=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/T-infra" + } + ], + "labels_url": "https://api.github.com/repos/rust-lang/rust/issues/107239/labels{/name}", + "locked": false, + "milestone": { + "closed_at": null, + "closed_issues": 270, + "created_at": "2023-01-22T13:22:36Z", + "creator": { + "avatar_url": "https://avatars.githubusercontent.com/u/47979223?v=4", + "events_url": "https://api.github.com/users/rustbot/events{/privacy}", + "followers_url": "https://api.github.com/users/rustbot/followers", + "following_url": "https://api.github.com/users/rustbot/following{/other_user}", + "gists_url": "https://api.github.com/users/rustbot/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rustbot", + "id": 47979223, + "login": "rustbot", + "node_id": "MDQ6VXNlcjQ3OTc5MjIz", + "organizations_url": "https://api.github.com/users/rustbot/orgs", + "received_events_url": "https://api.github.com/users/rustbot/received_events", + "repos_url": "https://api.github.com/users/rustbot/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rustbot/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rustbot/subscriptions", + "type": "User", + "url": "https://api.github.com/users/rustbot" + }, + "description": null, + "due_on": null, + "html_url": "https://github.com/rust-lang/rust/milestone/102", + "id": 8951616, + "labels_url": "https://api.github.com/repos/rust-lang/rust/milestones/102/labels", + "node_id": "MI_kwDOAAsO6M4AiJdA", + "number": 102, + "open_issues": 0, + "state": "open", + "title": "1.69.0", + "updated_at": "2023-02-05T20:33:07Z", + "url": "https://api.github.com/repos/rust-lang/rust/milestones/102" + }, + "node_id": "PR_kwDOAAsO6M5IXTOo", + "number": 107239, + "performed_via_github_app": null, + "pull_request": { + "diff_url": "https://github.com/rust-lang/rust/pull/107239.diff", + "html_url": "https://github.com/rust-lang/rust/pull/107239", + "merged_at": "2023-01-26T03:10:34Z", + "patch_url": "https://github.com/rust-lang/rust/pull/107239.patch", + "url": "https://api.github.com/repos/rust-lang/rust/pulls/107239" + }, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/rust-lang/rust/issues/107239/reactions" + }, + "repository_url": "https://api.github.com/repos/rust-lang/rust", + "score": 1.0, + "state": "closed", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/rust-lang/rust/issues/107239/timeline", + "title": "Bring tests back into rustc source tarball", + "updated_at": "2023-01-26T09:15:41Z", + "url": "https://api.github.com/repos/rust-lang/rust/issues/107239", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/51362316?v=4", + "events_url": "https://api.github.com/users/tmiasko/events{/privacy}", + "followers_url": "https://api.github.com/users/tmiasko/followers", + "following_url": "https://api.github.com/users/tmiasko/following{/other_user}", + "gists_url": "https://api.github.com/users/tmiasko/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/tmiasko", + "id": 51362316, + "login": "tmiasko", + "node_id": "MDQ6VXNlcjUxMzYyMzE2", + "organizations_url": "https://api.github.com/users/tmiasko/orgs", + "received_events_url": "https://api.github.com/users/tmiasko/received_events", + "repos_url": "https://api.github.com/users/tmiasko/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/tmiasko/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/tmiasko/subscriptions", + "type": "User", + "url": "https://api.github.com/users/tmiasko" + } + }, + { + "active_lock_reason": null, + "assignee": { + "avatar_url": "https://avatars.githubusercontent.com/u/1593513?v=4", + "events_url": "https://api.github.com/users/notriddle/events{/privacy}", + "followers_url": "https://api.github.com/users/notriddle/followers", + "following_url": "https://api.github.com/users/notriddle/following{/other_user}", + "gists_url": "https://api.github.com/users/notriddle/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/notriddle", + "id": 1593513, + "login": "notriddle", + "node_id": "MDQ6VXNlcjE1OTM1MTM=", + "organizations_url": "https://api.github.com/users/notriddle/orgs", + "received_events_url": "https://api.github.com/users/notriddle/received_events", + "repos_url": "https://api.github.com/users/notriddle/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/notriddle/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/notriddle/subscriptions", + "type": "User", + "url": "https://api.github.com/users/notriddle" + }, + "assignees": [ + { + "avatar_url": "https://avatars.githubusercontent.com/u/1593513?v=4", + "events_url": "https://api.github.com/users/notriddle/events{/privacy}", + "followers_url": "https://api.github.com/users/notriddle/followers", + "following_url": "https://api.github.com/users/notriddle/following{/other_user}", + "gists_url": "https://api.github.com/users/notriddle/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/notriddle", + "id": 1593513, + "login": "notriddle", + "node_id": "MDQ6VXNlcjE1OTM1MTM=", + "organizations_url": "https://api.github.com/users/notriddle/orgs", + "received_events_url": "https://api.github.com/users/notriddle/received_events", + "repos_url": "https://api.github.com/users/notriddle/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/notriddle/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/notriddle/subscriptions", + "type": "User", + "url": "https://api.github.com/users/notriddle" + } + ], + "author_association": "MEMBER", + "body": "Fixes https://github.com/rust-lang/rust/issues/107350.\r\n\r\nWe'll also need to backport this fix to beta.\r\n\r\nr? @notriddle ", + "closed_at": "2023-01-27T21:20:36Z", + "comments": 3, + "comments_url": "https://api.github.com/repos/rust-lang/rust/issues/107357/comments", + "created_at": "2023-01-27T11:11:41Z", + "draft": false, + "events_url": "https://api.github.com/repos/rust-lang/rust/issues/107357/events", + "html_url": "https://github.com/rust-lang/rust/pull/107357", + "id": 1559575358, + "labels": [ + { + "color": "bfd4f2", + "default": false, + "description": "Relevant to the rustdoc team, which will review and decide on the PR/issue.", + "id": 203738, + "name": "T-rustdoc", + "node_id": "MDU6TGFiZWwyMDM3Mzg=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/T-rustdoc" + }, + { + "color": "1e76d9", + "default": false, + "description": "Nominated for backporting to the compiler in the beta channel.", + "id": 201991156, + "name": "beta-nominated", + "node_id": "MDU6TGFiZWwyMDE5OTExNTY=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/beta-nominated" + }, + { + "color": "1e76d9", + "default": false, + "description": "Accepted for backporting to the compiler in the beta channel.", + "id": 203428830, + "name": "beta-accepted", + "node_id": "MDU6TGFiZWwyMDM0Mjg4MzA=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/beta-accepted" + }, + { + "color": "d3dddd", + "default": false, + "description": "Status: Waiting on bors to run and complete tests. Bors will change the label on completion.", + "id": 583437191, + "name": "S-waiting-on-bors", + "node_id": "MDU6TGFiZWw1ODM0MzcxOTE=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/S-waiting-on-bors" + } + ], + "labels_url": "https://api.github.com/repos/rust-lang/rust/issues/107357/labels{/name}", + "locked": false, + "milestone": { + "closed_at": null, + "closed_issues": 270, + "created_at": "2023-01-22T13:22:36Z", + "creator": { + "avatar_url": "https://avatars.githubusercontent.com/u/47979223?v=4", + "events_url": "https://api.github.com/users/rustbot/events{/privacy}", + "followers_url": "https://api.github.com/users/rustbot/followers", + "following_url": "https://api.github.com/users/rustbot/following{/other_user}", + "gists_url": "https://api.github.com/users/rustbot/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rustbot", + "id": 47979223, + "login": "rustbot", + "node_id": "MDQ6VXNlcjQ3OTc5MjIz", + "organizations_url": "https://api.github.com/users/rustbot/orgs", + "received_events_url": "https://api.github.com/users/rustbot/received_events", + "repos_url": "https://api.github.com/users/rustbot/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rustbot/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rustbot/subscriptions", + "type": "User", + "url": "https://api.github.com/users/rustbot" + }, + "description": null, + "due_on": null, + "html_url": "https://github.com/rust-lang/rust/milestone/102", + "id": 8951616, + "labels_url": "https://api.github.com/repos/rust-lang/rust/milestones/102/labels", + "node_id": "MI_kwDOAAsO6M4AiJdA", + "number": 102, + "open_issues": 0, + "state": "open", + "title": "1.69.0", + "updated_at": "2023-02-05T20:33:07Z", + "url": "https://api.github.com/repos/rust-lang/rust/milestones/102" + }, + "node_id": "PR_kwDOAAsO6M5Iqrzr", + "number": 107357, + "performed_via_github_app": null, + "pull_request": { + "diff_url": "https://github.com/rust-lang/rust/pull/107357.diff", + "html_url": "https://github.com/rust-lang/rust/pull/107357", + "merged_at": "2023-01-27T21:20:36Z", + "patch_url": "https://github.com/rust-lang/rust/pull/107357.patch", + "url": "https://api.github.com/repos/rust-lang/rust/pulls/107357" + }, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 1, + "total_count": 1, + "url": "https://api.github.com/repos/rust-lang/rust/issues/107357/reactions" + }, + "repository_url": "https://api.github.com/repos/rust-lang/rust", + "score": 1.0, + "state": "closed", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/rust-lang/rust/issues/107357/timeline", + "title": "Fix infinite loop in rustdoc get_all_import_attributes function", + "updated_at": "2023-02-01T22:14:14Z", + "url": "https://api.github.com/repos/rust-lang/rust/issues/107357", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/3050060?v=4", + "events_url": "https://api.github.com/users/GuillaumeGomez/events{/privacy}", + "followers_url": "https://api.github.com/users/GuillaumeGomez/followers", + "following_url": "https://api.github.com/users/GuillaumeGomez/following{/other_user}", + "gists_url": "https://api.github.com/users/GuillaumeGomez/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/GuillaumeGomez", + "id": 3050060, + "login": "GuillaumeGomez", + "node_id": "MDQ6VXNlcjMwNTAwNjA=", + "organizations_url": "https://api.github.com/users/GuillaumeGomez/orgs", + "received_events_url": "https://api.github.com/users/GuillaumeGomez/received_events", + "repos_url": "https://api.github.com/users/GuillaumeGomez/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/GuillaumeGomez/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/GuillaumeGomez/subscriptions", + "type": "User", + "url": "https://api.github.com/users/GuillaumeGomez" + } + }, + { + "active_lock_reason": null, + "assignee": { + "avatar_url": "https://avatars.githubusercontent.com/u/1822483?v=4", + "events_url": "https://api.github.com/users/cjgillot/events{/privacy}", + "followers_url": "https://api.github.com/users/cjgillot/followers", + "following_url": "https://api.github.com/users/cjgillot/following{/other_user}", + "gists_url": "https://api.github.com/users/cjgillot/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/cjgillot", + "id": 1822483, + "login": "cjgillot", + "node_id": "MDQ6VXNlcjE4MjI0ODM=", + "organizations_url": "https://api.github.com/users/cjgillot/orgs", + "received_events_url": "https://api.github.com/users/cjgillot/received_events", + "repos_url": "https://api.github.com/users/cjgillot/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/cjgillot/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/cjgillot/subscriptions", + "type": "User", + "url": "https://api.github.com/users/cjgillot" + }, + "assignees": [ + { + "avatar_url": "https://avatars.githubusercontent.com/u/1822483?v=4", + "events_url": "https://api.github.com/users/cjgillot/events{/privacy}", + "followers_url": "https://api.github.com/users/cjgillot/followers", + "following_url": "https://api.github.com/users/cjgillot/following{/other_user}", + "gists_url": "https://api.github.com/users/cjgillot/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/cjgillot", + "id": 1822483, + "login": "cjgillot", + "node_id": "MDQ6VXNlcjE4MjI0ODM=", + "organizations_url": "https://api.github.com/users/cjgillot/orgs", + "received_events_url": "https://api.github.com/users/cjgillot/received_events", + "repos_url": "https://api.github.com/users/cjgillot/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/cjgillot/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/cjgillot/subscriptions", + "type": "User", + "url": "https://api.github.com/users/cjgillot" + } + ], + "author_association": "MEMBER", + "body": "This includes a revert of https://github.com/rust-lang/rust/pull/105221 to restore fat archive reading with LlvmArchiveBuilder.\r\n\r\nShould fix #107162, #107334 and https://github.com/google/shaderc-rs/issues/133", + "closed_at": "2023-01-28T06:46:40Z", + "comments": 18, + "comments_url": "https://api.github.com/repos/rust-lang/rust/issues/107360/comments", + "created_at": "2023-01-27T11:52:10Z", + "draft": false, + "events_url": "https://api.github.com/repos/rust-lang/rust/issues/107360/events", + "html_url": "https://github.com/rust-lang/rust/pull/107360", + "id": 1559626690, + "labels": [ + { + "color": "1e76d9", + "default": false, + "description": "Nominated for backporting to the compiler in the beta channel.", + "id": 201991156, + "name": "beta-nominated", + "node_id": "MDU6TGFiZWwyMDE5OTExNTY=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/beta-nominated" + }, + { + "color": "1e76d9", + "default": false, + "description": "Accepted for backporting to the compiler in the beta channel.", + "id": 203428830, + "name": "beta-accepted", + "node_id": "MDU6TGFiZWwyMDM0Mjg4MzA=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/beta-accepted" + }, + { + "color": "bfd4f2", + "default": false, + "description": "Relevant to the compiler team, which will review and decide on the PR/issue.", + "id": 211668100, + "name": "T-compiler", + "node_id": "MDU6TGFiZWwyMTE2NjgxMDA=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/T-compiler" + }, + { + "color": "d3dddd", + "default": false, + "description": "Status: Waiting on bors to run and complete tests. Bors will change the label on completion.", + "id": 583437191, + "name": "S-waiting-on-bors", + "node_id": "MDU6TGFiZWw1ODM0MzcxOTE=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/S-waiting-on-bors" + }, + { + "color": "00229c", + "default": false, + "description": "Nominated for backporting to the compiler in the stable channel.", + "id": 980125335, + "name": "stable-nominated", + "node_id": "MDU6TGFiZWw5ODAxMjUzMzU=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/stable-nominated" + }, + { + "color": "00229c", + "default": false, + "description": "Accepted for backporting to the compiler in the stable channel.", + "id": 980125489, + "name": "stable-accepted", + "node_id": "MDU6TGFiZWw5ODAxMjU0ODk=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/stable-accepted" + }, + { + "color": "dae4e4", + "default": false, + "description": "This PR was explicitly merged by bors", + "id": 1223998418, + "name": "merged-by-bors", + "node_id": "MDU6TGFiZWwxMjIzOTk4NDE4", + "url": "https://api.github.com/repos/rust-lang/rust/labels/merged-by-bors" + }, + { + "color": "e4008a", + "default": false, + "description": "Performance regressions", + "id": 3116384996, + "name": "perf-regression", + "node_id": "MDU6TGFiZWwzMTE2Mzg0OTk2", + "url": "https://api.github.com/repos/rust-lang/rust/labels/perf-regression" + }, + { + "color": "e4008a", + "default": false, + "description": "The performance regression has been triaged.", + "id": 3145771546, + "name": "perf-regression-triaged", + "node_id": "MDU6TGFiZWwzMTQ1NzcxNTQ2", + "url": "https://api.github.com/repos/rust-lang/rust/labels/perf-regression-triaged" + } + ], + "labels_url": "https://api.github.com/repos/rust-lang/rust/issues/107360/labels{/name}", + "locked": false, + "milestone": { + "closed_at": null, + "closed_issues": 270, + "created_at": "2023-01-22T13:22:36Z", + "creator": { + "avatar_url": "https://avatars.githubusercontent.com/u/47979223?v=4", + "events_url": "https://api.github.com/users/rustbot/events{/privacy}", + "followers_url": "https://api.github.com/users/rustbot/followers", + "following_url": "https://api.github.com/users/rustbot/following{/other_user}", + "gists_url": "https://api.github.com/users/rustbot/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rustbot", + "id": 47979223, + "login": "rustbot", + "node_id": "MDQ6VXNlcjQ3OTc5MjIz", + "organizations_url": "https://api.github.com/users/rustbot/orgs", + "received_events_url": "https://api.github.com/users/rustbot/received_events", + "repos_url": "https://api.github.com/users/rustbot/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rustbot/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rustbot/subscriptions", + "type": "User", + "url": "https://api.github.com/users/rustbot" + }, + "description": null, + "due_on": null, + "html_url": "https://github.com/rust-lang/rust/milestone/102", + "id": 8951616, + "labels_url": "https://api.github.com/repos/rust-lang/rust/milestones/102/labels", + "node_id": "MI_kwDOAAsO6M4AiJdA", + "number": 102, + "open_issues": 0, + "state": "open", + "title": "1.69.0", + "updated_at": "2023-02-05T20:33:07Z", + "url": "https://api.github.com/repos/rust-lang/rust/milestones/102" + }, + "node_id": "PR_kwDOAAsO6M5Iq2_Z", + "number": 107360, + "performed_via_github_app": null, + "pull_request": { + "diff_url": "https://github.com/rust-lang/rust/pull/107360.diff", + "html_url": "https://github.com/rust-lang/rust/pull/107360", + "merged_at": "2023-01-28T06:46:40Z", + "patch_url": "https://github.com/rust-lang/rust/pull/107360.patch", + "url": "https://api.github.com/repos/rust-lang/rust/pulls/107360" + }, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/rust-lang/rust/issues/107360/reactions" + }, + "repository_url": "https://api.github.com/repos/rust-lang/rust", + "score": 1.0, + "state": "closed", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/rust-lang/rust/issues/107360/timeline", + "title": "Fix thin archive reading", + "updated_at": "2023-02-02T20:35:26Z", + "url": "https://api.github.com/repos/rust-lang/rust/issues/107360", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/17426603?v=4", + "events_url": "https://api.github.com/users/bjorn3/events{/privacy}", + "followers_url": "https://api.github.com/users/bjorn3/followers", + "following_url": "https://api.github.com/users/bjorn3/following{/other_user}", + "gists_url": "https://api.github.com/users/bjorn3/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bjorn3", + "id": 17426603, + "login": "bjorn3", + "node_id": "MDQ6VXNlcjE3NDI2NjAz", + "organizations_url": "https://api.github.com/users/bjorn3/orgs", + "received_events_url": "https://api.github.com/users/bjorn3/received_events", + "repos_url": "https://api.github.com/users/bjorn3/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bjorn3/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bjorn3/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bjorn3" + } + } + ], + "total_count": 3 + } +} diff --git a/tests/github_client/get_reference/00-GET-repos_rust-lang_rust.json b/tests/github_client/get_reference/00-GET-repos_rust-lang_rust.json new file mode 100644 index 00000000..3589a6e8 --- /dev/null +++ b/tests/github_client/get_reference/00-GET-repos_rust-lang_rust.json @@ -0,0 +1,160 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": false, + "allow_squash_merge": false, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "delete_branch_on_merge": true, + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10326, + "forks_count": 10326, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "network_count": 10326, + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9513, + "open_issues_count": 9513, + "organization": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "permissions": { + "admin": false, + "maintain": false, + "pull": true, + "push": true, + "triage": true + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T18:16:26Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066392, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77402, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_count": 1487, + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "temp_clone_token": "", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T19:09:47Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 77402, + "watchers_count": 77402, + "web_commit_signoff_required": false + } +} diff --git a/tests/github_client/get_reference/01-GET-repos_rust-lang_rust_git_ref_heads_stable.json b/tests/github_client/get_reference/01-GET-repos_rust-lang_rust_git_ref_heads_stable.json new file mode 100644 index 00000000..b2a68fa9 --- /dev/null +++ b/tests/github_client/get_reference/01-GET-repos_rust-lang_rust_git_ref_heads_stable.json @@ -0,0 +1,18 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust/git/ref/heads/stable", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "node_id": "MDM6UmVmNzI0NzEyOnJlZnMvaGVhZHMvc3RhYmxl", + "object": { + "sha": "fc594f15669680fa70d255faec3ca3fb507c3405", + "type": "commit", + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/fc594f15669680fa70d255faec3ca3fb507c3405" + }, + "ref": "refs/heads/stable", + "url": "https://api.github.com/repos/rust-lang/rust/git/refs/heads/stable" + } +} diff --git a/tests/github_client/git_commit/00-GET-repos_rust-lang_rust.json b/tests/github_client/git_commit/00-GET-repos_rust-lang_rust.json new file mode 100644 index 00000000..a1ab4e0a --- /dev/null +++ b/tests/github_client/git_commit/00-GET-repos_rust-lang_rust.json @@ -0,0 +1,148 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10323, + "forks_count": 10323, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "network_count": 10323, + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9508, + "open_issues_count": 9508, + "organization": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "permissions": { + "admin": false, + "maintain": false, + "pull": true, + "push": true, + "triage": true + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T14:37:25Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066289, + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77396, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_count": 1488, + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T14:42:37Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "visibility": "public", + "watchers": 77396, + "watchers_count": 77396, + "web_commit_signoff_required": false + } +} diff --git a/tests/github_client/git_commit/01-GET-repos_rust-lang_rust_git_commits_109cccbe4f345c0f0785ce860788580c3e2a29f5.json b/tests/github_client/git_commit/01-GET-repos_rust-lang_rust_git_commits_109cccbe4f345c0f0785ce860788580c3e2a29f5.json new file mode 100644 index 00000000..40cc3973 --- /dev/null +++ b/tests/github_client/git_commit/01-GET-repos_rust-lang_rust_git_commits_109cccbe4f345c0f0785ce860788580c3e2a29f5.json @@ -0,0 +1,47 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust/git/commits/109cccbe4f345c0f0785ce860788580c3e2a29f5", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "author": { + "date": "2022-12-13T07:10:53Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "committer": { + "date": "2022-12-13T07:10:53Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "html_url": "https://github.com/rust-lang/rust/commit/109cccbe4f345c0f0785ce860788580c3e2a29f5", + "message": "Auto merge of #105350 - compiler-errors:faster-binder-relate, r=oli-obk\n\nFast-path some binder relations\n\nA simpler approach than #104598\n\nFixes #104583\n\nr? types", + "node_id": "C_kwDOAAsO6NoAKDEwOWNjY2JlNGYzNDVjMGYwNzg1Y2U4NjA3ODg1ODBjM2UyYTI5ZjU", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/71ec1457ee9868a838e4521a3510cdd416c0c295", + "sha": "71ec1457ee9868a838e4521a3510cdd416c0c295", + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/71ec1457ee9868a838e4521a3510cdd416c0c295" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/2025a96ee1a699722da73993995b6f0572374757", + "sha": "2025a96ee1a699722da73993995b6f0572374757", + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/2025a96ee1a699722da73993995b6f0572374757" + } + ], + "sha": "109cccbe4f345c0f0785ce860788580c3e2a29f5", + "tree": { + "sha": "e67d87c61892169977204cc2e3fd89b2a19e13bb", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/e67d87c61892169977204cc2e3fd89b2a19e13bb" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/109cccbe4f345c0f0785ce860788580c3e2a29f5", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + } +} diff --git a/tests/github_client/is_new_contributor/00-GET-repos_rust-lang_rust.json b/tests/github_client/is_new_contributor/00-GET-repos_rust-lang_rust.json new file mode 100644 index 00000000..2ec17b5e --- /dev/null +++ b/tests/github_client/is_new_contributor/00-GET-repos_rust-lang_rust.json @@ -0,0 +1,148 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10323, + "forks_count": 10323, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "network_count": 10323, + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9504, + "open_issues_count": 9504, + "organization": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "permissions": { + "admin": false, + "maintain": false, + "pull": true, + "push": true, + "triage": true + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T14:10:34Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066264, + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77394, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_count": 1488, + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T14:20:35Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "visibility": "public", + "watchers": 77394, + "watchers_count": 77394, + "web_commit_signoff_required": false + } +} diff --git a/tests/github_client/is_new_contributor/01-GET-repos_rust-lang_rust_commits.json b/tests/github_client/is_new_contributor/01-GET-repos_rust-lang_rust_commits.json new file mode 100644 index 00000000..d7219399 --- /dev/null +++ b/tests/github_client/is_new_contributor/01-GET-repos_rust-lang_rust_commits.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust/commits", + "query": "author=octocat", + "request_body": "", + "response_code": 200, + "response_body": [] +} diff --git a/tests/github_client/is_new_contributor/02-GET-repos_rust-lang_rust_commits.json b/tests/github_client/is_new_contributor/02-GET-repos_rust-lang_rust_commits.json new file mode 100644 index 00000000..4fcaca4f --- /dev/null +++ b/tests/github_client/is_new_contributor/02-GET-repos_rust-lang_rust_commits.json @@ -0,0 +1,2380 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust/commits", + "query": "author=brson", + "request_body": "", + "response_code": 200, + "response_body": [ + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/356848c9b9a3bd8226bbabd08611b1e519acc9c7/comments", + "commit": { + "author": { + "date": "2020-05-07T02:42:12Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2020-05-07T02:42:12Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "message": "Add two more TiKV bugs to trophy case", + "tree": { + "sha": "d1aae96f10ecb490d6caebc63de18f34885cb73d", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/d1aae96f10ecb490d6caebc63de18f34885cb73d" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/356848c9b9a3bd8226bbabd08611b1e519acc9c7", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/356848c9b9a3bd8226bbabd08611b1e519acc9c7", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjM1Njg0OGM5YjlhM2JkODIyNmJiYWJkMDg2MTFiMWU1MTlhY2M5Yzc=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/308458a4ab210da24c8fd481d0f930e50f512886", + "sha": "308458a4ab210da24c8fd481d0f930e50f512886", + "url": "https://api.github.com/repos/rust-lang/rust/commits/308458a4ab210da24c8fd481d0f930e50f512886" + } + ], + "sha": "356848c9b9a3bd8226bbabd08611b1e519acc9c7", + "url": "https://api.github.com/repos/rust-lang/rust/commits/356848c9b9a3bd8226bbabd08611b1e519acc9c7" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/5e25dfaef83d1a2855cc4e4a1aecca77ba0dc47a/comments", + "commit": { + "author": { + "date": "2020-05-01T21:34:16Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2020-05-01T21:34:16Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "message": "Add another tikv stacked borrowing error to trophy case", + "tree": { + "sha": "bbf63e95c9e9eac80d7f92875061c05352759cac", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/bbf63e95c9e9eac80d7f92875061c05352759cac" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/5e25dfaef83d1a2855cc4e4a1aecca77ba0dc47a", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/5e25dfaef83d1a2855cc4e4a1aecca77ba0dc47a", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjVlMjVkZmFlZjgzZDFhMjg1NWNjNGU0YTFhZWNjYTc3YmEwZGM0N2E=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/d606172f32a4ca6c6ce73147760ee0ca1ed439b9", + "sha": "d606172f32a4ca6c6ce73147760ee0ca1ed439b9", + "url": "https://api.github.com/repos/rust-lang/rust/commits/d606172f32a4ca6c6ce73147760ee0ca1ed439b9" + } + ], + "sha": "5e25dfaef83d1a2855cc4e4a1aecca77ba0dc47a", + "url": "https://api.github.com/repos/rust-lang/rust/commits/5e25dfaef83d1a2855cc4e4a1aecca77ba0dc47a" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/488f3801e2a22afb093d03cf176169d91212374c/comments", + "commit": { + "author": { + "date": "2020-04-30T00:03:43Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2020-04-30T00:03:43Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "message": "Add servo_arc to trophy case", + "tree": { + "sha": "bb1cf8cc877de4c14875aed208aca50321759c7f", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/bb1cf8cc877de4c14875aed208aca50321759c7f" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/488f3801e2a22afb093d03cf176169d91212374c", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/488f3801e2a22afb093d03cf176169d91212374c", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjQ4OGYzODAxZTJhMjJhZmIwOTNkMDNjZjE3NjE2OWQ5MTIxMjM3NGM=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/dc91c172a469b51cf038d97e361458cd09b13fbd", + "sha": "dc91c172a469b51cf038d97e361458cd09b13fbd", + "url": "https://api.github.com/repos/rust-lang/rust/commits/dc91c172a469b51cf038d97e361458cd09b13fbd" + } + ], + "sha": "488f3801e2a22afb093d03cf176169d91212374c", + "url": "https://api.github.com/repos/rust-lang/rust/commits/488f3801e2a22afb093d03cf176169d91212374c" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/f84aa4a424221a8b3739f6232fec8f419d176fba/comments", + "commit": { + "author": { + "date": "2020-04-23T08:46:36Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2020-04-23T08:46:36Z", + "email": "noreply@github.com", + "name": "GitHub" + }, + "message": "Update README.md\n\nCo-Authored-By: Ralf Jung ", + "tree": { + "sha": "9ad87c344ce2232649af262bad2e4b10d7b5cddc", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/9ad87c344ce2232649af262bad2e4b10d7b5cddc" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/f84aa4a424221a8b3739f6232fec8f419d176fba", + "verification": { + "payload": "tree 9ad87c344ce2232649af262bad2e4b10d7b5cddc\nparent 5b60f0df2afba76fb6bd4cc3ae0c85ea2cfd484c\nauthor Brian Anderson 1587631596 -0600\ncommitter GitHub 1587631596 -0600\n\nUpdate README.md\n\nCo-Authored-By: Ralf Jung ", + "reason": "valid", + "signature": "-----BEGIN PGP SIGNATURE-----\n\nwsBcBAABCAAQBQJeoVXsCRBK7hj4Ov3rIwAAdHIIAEronL6vj95tRmI+HCoqJLnv\nV4gQKYjvo5MQCrh7l/XmrYnLpwtHp40KBdE429LYyKCIG8wVXyC8BvWh9/2kMmC2\ne2XwoNUPnl5lCwprpEKGKPoCGKgctj57EAyF81PQ0Vtpo3krm6YGHsEUagw8h9VC\nTB23Rajqj43eesqjj0V5iuTYOlePHJmGo6NVrOIFJ8Xj3OquJQ0JQRF5xN6esvaa\nAuQDHHlCPuM4bzTqvL+Z0HsCkA+Y6mCS+5eK2vpiYzIoxuSytA98YPaMbCZIDWl3\nK6G/kvhCHqeKhZk0jhL1rdOKsxlASq+q8o0/l/hq8Jo+dDSaV6YL00aIa+5J7K4=\n=Es7I\n-----END PGP SIGNATURE-----\n", + "verified": true + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/19864447?v=4", + "events_url": "https://api.github.com/users/web-flow/events{/privacy}", + "followers_url": "https://api.github.com/users/web-flow/followers", + "following_url": "https://api.github.com/users/web-flow/following{/other_user}", + "gists_url": "https://api.github.com/users/web-flow/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/web-flow", + "id": 19864447, + "login": "web-flow", + "node_id": "MDQ6VXNlcjE5ODY0NDQ3", + "organizations_url": "https://api.github.com/users/web-flow/orgs", + "received_events_url": "https://api.github.com/users/web-flow/received_events", + "repos_url": "https://api.github.com/users/web-flow/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/web-flow/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/web-flow/subscriptions", + "type": "User", + "url": "https://api.github.com/users/web-flow" + }, + "html_url": "https://github.com/rust-lang/rust/commit/f84aa4a424221a8b3739f6232fec8f419d176fba", + "node_id": "MDY6Q29tbWl0NzI0NzEyOmY4NGFhNGE0MjQyMjFhOGIzNzM5ZjYyMzJmZWM4ZjQxOWQxNzZmYmE=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/5b60f0df2afba76fb6bd4cc3ae0c85ea2cfd484c", + "sha": "5b60f0df2afba76fb6bd4cc3ae0c85ea2cfd484c", + "url": "https://api.github.com/repos/rust-lang/rust/commits/5b60f0df2afba76fb6bd4cc3ae0c85ea2cfd484c" + } + ], + "sha": "f84aa4a424221a8b3739f6232fec8f419d176fba", + "url": "https://api.github.com/repos/rust-lang/rust/commits/f84aa4a424221a8b3739f6232fec8f419d176fba" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/5b60f0df2afba76fb6bd4cc3ae0c85ea2cfd484c/comments", + "commit": { + "author": { + "date": "2020-04-23T02:37:58Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2020-04-23T02:37:58Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "message": "Add ryu and tikv to trophy case", + "tree": { + "sha": "2ddce8338ebb8ede25e8f06e8cc61a6f4273477a", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/2ddce8338ebb8ede25e8f06e8cc61a6f4273477a" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/5b60f0df2afba76fb6bd4cc3ae0c85ea2cfd484c", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/5b60f0df2afba76fb6bd4cc3ae0c85ea2cfd484c", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjViNjBmMGRmMmFmYmE3NmZiNmJkNGNjM2FlMGM4NWVhMmNmZDQ4NGM=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/26baf87e4300386910f9db7545edf784dbec88f0", + "sha": "26baf87e4300386910f9db7545edf784dbec88f0", + "url": "https://api.github.com/repos/rust-lang/rust/commits/26baf87e4300386910f9db7545edf784dbec88f0" + } + ], + "sha": "5b60f0df2afba76fb6bd4cc3ae0c85ea2cfd484c", + "url": "https://api.github.com/repos/rust-lang/rust/commits/5b60f0df2afba76fb6bd4cc3ae0c85ea2cfd484c" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/8251e12950159c5802dd3995b14be7cf4fa99acd/comments", + "commit": { + "author": { + "date": "2020-02-07T05:59:43Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2020-02-07T06:08:24Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "message": "Don't use the word 'unwrap' to describe core unwrapping functions\n\nIt's tautological, and Rust-specific Jargon.\n\nThis changes various Option/Result methods to consistently describe unwrapping\nbehavior using the words \"return\", \"contain\", \"consume\".\n\nIt also renames the closure argument of `Return::unwrap_or_else` to `default` to\nbe consistent with `Option`.", + "tree": { + "sha": "177c908c8430b6db3de38d8245f90f52b3a8bcb4", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/177c908c8430b6db3de38d8245f90f52b3a8bcb4" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/8251e12950159c5802dd3995b14be7cf4fa99acd", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/8251e12950159c5802dd3995b14be7cf4fa99acd", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjgyNTFlMTI5NTAxNTljNTgwMmRkMzk5NWIxNGJlN2NmNGZhOTlhY2Q=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/db9b578b71190540cfd84f16f5d310d6ce4cb659", + "sha": "db9b578b71190540cfd84f16f5d310d6ce4cb659", + "url": "https://api.github.com/repos/rust-lang/rust/commits/db9b578b71190540cfd84f16f5d310d6ce4cb659" + } + ], + "sha": "8251e12950159c5802dd3995b14be7cf4fa99acd", + "url": "https://api.github.com/repos/rust-lang/rust/commits/8251e12950159c5802dd3995b14be7cf4fa99acd" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/db9b578b71190540cfd84f16f5d310d6ce4cb659/comments", + "commit": { + "author": { + "date": "2020-02-05T08:31:12Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2020-02-05T08:31:12Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "message": "Reorder declarations of Result::expect_err/unwrap_err to match Option", + "tree": { + "sha": "0671d8d006f16ecda7e1fc9c3fe896e8365262db", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/0671d8d006f16ecda7e1fc9c3fe896e8365262db" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/db9b578b71190540cfd84f16f5d310d6ce4cb659", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/db9b578b71190540cfd84f16f5d310d6ce4cb659", + "node_id": "MDY6Q29tbWl0NzI0NzEyOmRiOWI1NzhiNzExOTA1NDBjZmQ4NGYxNmY1ZDMxMGQ2Y2U0Y2I2NTk=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/c00d8aa5179ef38f7d83067a8d010bcc26fa0cc3", + "sha": "c00d8aa5179ef38f7d83067a8d010bcc26fa0cc3", + "url": "https://api.github.com/repos/rust-lang/rust/commits/c00d8aa5179ef38f7d83067a8d010bcc26fa0cc3" + } + ], + "sha": "db9b578b71190540cfd84f16f5d310d6ce4cb659", + "url": "https://api.github.com/repos/rust-lang/rust/commits/db9b578b71190540cfd84f16f5d310d6ce4cb659" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/c00d8aa5179ef38f7d83067a8d010bcc26fa0cc3/comments", + "commit": { + "author": { + "date": "2020-02-05T08:28:13Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2020-02-05T08:28:13Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "message": "Reorder declarations of Result::export/unwrap to match Option", + "tree": { + "sha": "cc6b233e2980bfef35e4e80ce89bc17bbeab7a7e", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/cc6b233e2980bfef35e4e80ce89bc17bbeab7a7e" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/c00d8aa5179ef38f7d83067a8d010bcc26fa0cc3", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/c00d8aa5179ef38f7d83067a8d010bcc26fa0cc3", + "node_id": "MDY6Q29tbWl0NzI0NzEyOmMwMGQ4YWE1MTc5ZWYzOGY3ZDgzMDY3YThkMDEwYmNjMjZmYTBjYzM=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/002287d25f6ef9718dbabd3e23c00b5ebcfb51c1", + "sha": "002287d25f6ef9718dbabd3e23c00b5ebcfb51c1", + "url": "https://api.github.com/repos/rust-lang/rust/commits/002287d25f6ef9718dbabd3e23c00b5ebcfb51c1" + } + ], + "sha": "c00d8aa5179ef38f7d83067a8d010bcc26fa0cc3", + "url": "https://api.github.com/repos/rust-lang/rust/commits/c00d8aa5179ef38f7d83067a8d010bcc26fa0cc3" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/c03077b23accd0a5b074e298538bb0557b0be9da/comments", + "commit": { + "author": { + "date": "2019-08-07T21:51:49Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2019-08-07T21:51:49Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "message": "Use consistent capitalization in -C/-Z help", + "tree": { + "sha": "69694ee015d20794275fc866d70895236f2029eb", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/69694ee015d20794275fc866d70895236f2029eb" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/c03077b23accd0a5b074e298538bb0557b0be9da", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/c03077b23accd0a5b074e298538bb0557b0be9da", + "node_id": "MDY6Q29tbWl0NzI0NzEyOmMwMzA3N2IyM2FjY2QwYTViMDc0ZTI5ODUzOGJiMDU1N2IwYmU5ZGE=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/ad7c55e1fc55d9af4787b285cec1c64e3480ae84", + "sha": "ad7c55e1fc55d9af4787b285cec1c64e3480ae84", + "url": "https://api.github.com/repos/rust-lang/rust/commits/ad7c55e1fc55d9af4787b285cec1c64e3480ae84" + } + ], + "sha": "c03077b23accd0a5b074e298538bb0557b0be9da", + "url": "https://api.github.com/repos/rust-lang/rust/commits/c03077b23accd0a5b074e298538bb0557b0be9da" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/f4d6362518432ff7a26339cdef83e29e4ae6e7d1/comments", + "commit": { + "author": { + "date": "2018-08-21T06:09:15Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2018-08-21T06:09:15Z", + "email": "andersrb@gmail.com", + "name": "Brian Anderson" + }, + "message": "librustc_lint: In recursion warning, change 'recurring' to 'recursing'", + "tree": { + "sha": "3fd3bd7b20a49529d6d4c50ca821e4019c700d39", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/3fd3bd7b20a49529d6d4c50ca821e4019c700d39" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/f4d6362518432ff7a26339cdef83e29e4ae6e7d1", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/f4d6362518432ff7a26339cdef83e29e4ae6e7d1", + "node_id": "MDY6Q29tbWl0NzI0NzEyOmY0ZDYzNjI1MTg0MzJmZjdhMjYzMzljZGVmODNlMjllNGFlNmU3ZDE=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/bfc3b20663e1abfff0499332f9168f60c3269c33", + "sha": "bfc3b20663e1abfff0499332f9168f60c3269c33", + "url": "https://api.github.com/repos/rust-lang/rust/commits/bfc3b20663e1abfff0499332f9168f60c3269c33" + } + ], + "sha": "f4d6362518432ff7a26339cdef83e29e4ae6e7d1", + "url": "https://api.github.com/repos/rust-lang/rust/commits/f4d6362518432ff7a26339cdef83e29e4ae6e7d1" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/e8689c7de71f822dca891099a94c9377c36e46b2/comments", + "commit": { + "author": { + "date": "2017-06-06T02:07:43Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2017-06-06T21:51:17Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Fix setting PATH during linkage on windows-gnu", + "tree": { + "sha": "1164ef1f9278df4e473b272970386e8d391cb4ee", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/1164ef1f9278df4e473b272970386e8d391cb4ee" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/e8689c7de71f822dca891099a94c9377c36e46b2", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/e8689c7de71f822dca891099a94c9377c36e46b2", + "node_id": "MDY6Q29tbWl0NzI0NzEyOmU4Njg5YzdkZTcxZjgyMmRjYTg5MTA5OWE5NGM5Mzc3YzM2ZTQ2YjI=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/d015610db7b7d30f3c92d3272ce166397a81349e", + "sha": "d015610db7b7d30f3c92d3272ce166397a81349e", + "url": "https://api.github.com/repos/rust-lang/rust/commits/d015610db7b7d30f3c92d3272ce166397a81349e" + } + ], + "sha": "e8689c7de71f822dca891099a94c9377c36e46b2", + "url": "https://api.github.com/repos/rust-lang/rust/commits/e8689c7de71f822dca891099a94c9377c36e46b2" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/da100fe0bb7ba77dbcc346018068dbfdba053f6b/comments", + "commit": { + "author": { + "date": "2017-05-24T02:02:23Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2017-06-01T20:41:38Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Support VS 2017\n\nFixes #38584", + "tree": { + "sha": "6bd4b44d0ffb24e29ff297a3b9cca73cc884cb51", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/6bd4b44d0ffb24e29ff297a3b9cca73cc884cb51" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/da100fe0bb7ba77dbcc346018068dbfdba053f6b", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/da100fe0bb7ba77dbcc346018068dbfdba053f6b", + "node_id": "MDY6Q29tbWl0NzI0NzEyOmRhMTAwZmUwYmI3YmE3N2RiY2MzNDYwMTgwNjhkYmZkYmEwNTNmNmI=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/f89d8d184490ecb3cf91f7b6bb7296d649f931ba", + "sha": "f89d8d184490ecb3cf91f7b6bb7296d649f931ba", + "url": "https://api.github.com/repos/rust-lang/rust/commits/f89d8d184490ecb3cf91f7b6bb7296d649f931ba" + } + ], + "sha": "da100fe0bb7ba77dbcc346018068dbfdba053f6b", + "url": "https://api.github.com/repos/rust-lang/rust/commits/da100fe0bb7ba77dbcc346018068dbfdba053f6b" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/435e1cec9e63ee9651a0c082b050b5c49da96c10/comments", + "commit": { + "author": { + "date": "2017-05-25T18:48:21Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2017-05-25T18:48:21Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Remove stray lockfile", + "tree": { + "sha": "0c885694a05cad6de8608274cd77c94dee3952c2", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/0c885694a05cad6de8608274cd77c94dee3952c2" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/435e1cec9e63ee9651a0c082b050b5c49da96c10", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/435e1cec9e63ee9651a0c082b050b5c49da96c10", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjQzNWUxY2VjOWU2M2VlOTY1MWEwYzA4MmIwNTBiNWM0OWRhOTZjMTA=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/deb90c33ccee849821de5f3a8e26d8d9a2e774e5", + "sha": "deb90c33ccee849821de5f3a8e26d8d9a2e774e5", + "url": "https://api.github.com/repos/rust-lang/rust/commits/deb90c33ccee849821de5f3a8e26d8d9a2e774e5" + } + ], + "sha": "435e1cec9e63ee9651a0c082b050b5c49da96c10", + "url": "https://api.github.com/repos/rust-lang/rust/commits/435e1cec9e63ee9651a0c082b050b5c49da96c10" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/084b67f56a66b440657e6aa66227e971790a87a4/comments", + "commit": { + "author": { + "date": "2017-05-11T19:19:21Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2017-05-11T19:19:21Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Annotate the license exceptions", + "tree": { + "sha": "76d18318db67774b1e0c2721551d6f0c7fcd2560", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/76d18318db67774b1e0c2721551d6f0c7fcd2560" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/084b67f56a66b440657e6aa66227e971790a87a4", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/084b67f56a66b440657e6aa66227e971790a87a4", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjA4NGI2N2Y1NmE2NmI0NDA2NTdlNmFhNjYyMjdlOTcxNzkwYTg3YTQ=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/2cc3358e4f1c4a79685745a461a1be1ce784b88a", + "sha": "2cc3358e4f1c4a79685745a461a1be1ce784b88a", + "url": "https://api.github.com/repos/rust-lang/rust/commits/2cc3358e4f1c4a79685745a461a1be1ce784b88a" + } + ], + "sha": "084b67f56a66b440657e6aa66227e971790a87a4", + "url": "https://api.github.com/repos/rust-lang/rust/commits/084b67f56a66b440657e6aa66227e971790a87a4" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/f59931dc176aafcf6f05dff27f7015c0a61d73d4/comments", + "commit": { + "author": { + "date": "2017-05-05T07:03:30Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2017-05-05T07:03:30Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Update rust-installer to fix rust-lang-nursery/rustup.rs#1092", + "tree": { + "sha": "88641f2c3492ab244128891348b44f348a676d7c", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/88641f2c3492ab244128891348b44f348a676d7c" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/f59931dc176aafcf6f05dff27f7015c0a61d73d4", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/f59931dc176aafcf6f05dff27f7015c0a61d73d4", + "node_id": "MDY6Q29tbWl0NzI0NzEyOmY1OTkzMWRjMTc2YWFmY2Y2ZjA1ZGZmMjdmNzAxNWMwYTYxZDczZDQ=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/a6ab049ed1db09f693df7d33046b3980f56751c1", + "sha": "a6ab049ed1db09f693df7d33046b3980f56751c1", + "url": "https://api.github.com/repos/rust-lang/rust/commits/a6ab049ed1db09f693df7d33046b3980f56751c1" + } + ], + "sha": "f59931dc176aafcf6f05dff27f7015c0a61d73d4", + "url": "https://api.github.com/repos/rust-lang/rust/commits/f59931dc176aafcf6f05dff27f7015c0a61d73d4" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/8e97693b2cbcaeb745643ee1b37058e8dde2efa1/comments", + "commit": { + "author": { + "date": "2017-04-25T17:43:33Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2017-04-27T16:18:26Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Update release notes for 1.17", + "tree": { + "sha": "9ad9c28b58e06b74e7e2dcbb3523ed27c26ace3d", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/9ad9c28b58e06b74e7e2dcbb3523ed27c26ace3d" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/8e97693b2cbcaeb745643ee1b37058e8dde2efa1", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/8e97693b2cbcaeb745643ee1b37058e8dde2efa1", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjhlOTc2OTNiMmNiY2FlYjc0NTY0M2VlMWIzNzA1OGU4ZGRlMmVmYTE=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/c7e724a148fbc1ca46508d953302b697ff35af16", + "sha": "c7e724a148fbc1ca46508d953302b697ff35af16", + "url": "https://api.github.com/repos/rust-lang/rust/commits/c7e724a148fbc1ca46508d953302b697ff35af16" + } + ], + "sha": "8e97693b2cbcaeb745643ee1b37058e8dde2efa1", + "url": "https://api.github.com/repos/rust-lang/rust/commits/8e97693b2cbcaeb745643ee1b37058e8dde2efa1" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/1c3f34dba6a8219822a48f3db7e6f50ff04e0f78/comments", + "commit": { + "author": { + "date": "2017-04-10T20:50:42Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2017-04-10T20:50:57Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Convert HashMap to BTree in build-manifest", + "tree": { + "sha": "8ff2ed16984f9b49e9d2992aac18be2942d9a18e", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/8ff2ed16984f9b49e9d2992aac18be2942d9a18e" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/1c3f34dba6a8219822a48f3db7e6f50ff04e0f78", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/1c3f34dba6a8219822a48f3db7e6f50ff04e0f78", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjFjM2YzNGRiYTZhODIxOTgyMmE0OGYzZGI3ZTZmNTBmZjA0ZTBmNzg=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/8493dd6d6e8f5e1280ae3dc05135a7e2897c36ac", + "sha": "8493dd6d6e8f5e1280ae3dc05135a7e2897c36ac", + "url": "https://api.github.com/repos/rust-lang/rust/commits/8493dd6d6e8f5e1280ae3dc05135a7e2897c36ac" + } + ], + "sha": "1c3f34dba6a8219822a48f3db7e6f50ff04e0f78", + "url": "https://api.github.com/repos/rust-lang/rust/commits/1c3f34dba6a8219822a48f3db7e6f50ff04e0f78" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/3554ff32db74b431dfb356cc4533514544c67bf9/comments", + "commit": { + "author": { + "date": "2017-03-14T19:31:20Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2017-03-14T19:31:20Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Make docs required again", + "tree": { + "sha": "ed29487b87eb2d44d699ca6ebeb603d887c720dc", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/ed29487b87eb2d44d699ca6ebeb603d887c720dc" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/3554ff32db74b431dfb356cc4533514544c67bf9", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/3554ff32db74b431dfb356cc4533514544c67bf9", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjM1NTRmZjMyZGI3NGI0MzFkZmIzNTZjYzQ1MzM1MTQ1NDRjNjdiZjk=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/6f10e2f63de720468e2b4bfcb275e4b90b1f9870", + "sha": "6f10e2f63de720468e2b4bfcb275e4b90b1f9870", + "url": "https://api.github.com/repos/rust-lang/rust/commits/6f10e2f63de720468e2b4bfcb275e4b90b1f9870" + } + ], + "sha": "3554ff32db74b431dfb356cc4533514544c67bf9", + "url": "https://api.github.com/repos/rust-lang/rust/commits/3554ff32db74b431dfb356cc4533514544c67bf9" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/23c09eaa770c0bdc40dc744a4086dbe7976b4662/comments", + "commit": { + "author": { + "date": "2017-02-15T02:52:28Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2017-03-09T21:35:44Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Release notes for 1.16", + "tree": { + "sha": "a4408577cec6dbbecdf49571ba69413814dd5675", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/a4408577cec6dbbecdf49571ba69413814dd5675" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/23c09eaa770c0bdc40dc744a4086dbe7976b4662", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/23c09eaa770c0bdc40dc744a4086dbe7976b4662", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjIzYzA5ZWFhNzcwYzBiZGM0MGRjNzQ0YTQwODZkYmU3OTc2YjQ2NjI=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/3087a1f39eaeac9d76c8b159dcc64de515bb2b83", + "sha": "3087a1f39eaeac9d76c8b159dcc64de515bb2b83", + "url": "https://api.github.com/repos/rust-lang/rust/commits/3087a1f39eaeac9d76c8b159dcc64de515bb2b83" + } + ], + "sha": "23c09eaa770c0bdc40dc744a4086dbe7976b4662", + "url": "https://api.github.com/repos/rust-lang/rust/commits/23c09eaa770c0bdc40dc744a4086dbe7976b4662" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/e77f8568f67b6dc265a620f7506a6f931c3a002e/comments", + "commit": { + "author": { + "date": "2017-02-14T04:10:52Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2017-02-15T23:03:39Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Add a test that -fPIC is applied", + "tree": { + "sha": "e13aba6b336b11221975e21d64784370e87a5a89", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/e13aba6b336b11221975e21d64784370e87a5a89" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/e77f8568f67b6dc265a620f7506a6f931c3a002e", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/e77f8568f67b6dc265a620f7506a6f931c3a002e", + "node_id": "MDY6Q29tbWl0NzI0NzEyOmU3N2Y4NTY4ZjY3YjZkYzI2NWE2MjBmNzUwNmE2ZjkzMWMzYTAwMmU=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/c781fc4a6a8af287f7abe141f035a638bc0165c3", + "sha": "c781fc4a6a8af287f7abe141f035a638bc0165c3", + "url": "https://api.github.com/repos/rust-lang/rust/commits/c781fc4a6a8af287f7abe141f035a638bc0165c3" + } + ], + "sha": "e77f8568f67b6dc265a620f7506a6f931c3a002e", + "url": "https://api.github.com/repos/rust-lang/rust/commits/e77f8568f67b6dc265a620f7506a6f931c3a002e" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/e491f399147aaf09f631878d009396fc5400ddfd/comments", + "commit": { + "author": { + "date": "2017-02-10T00:30:02Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2017-02-10T00:30:02Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Update 1.15.1 relnotes", + "tree": { + "sha": "d4b0ee97fddb111aa74498380dedcaffbb4948ed", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/d4b0ee97fddb111aa74498380dedcaffbb4948ed" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/e491f399147aaf09f631878d009396fc5400ddfd", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/e491f399147aaf09f631878d009396fc5400ddfd", + "node_id": "MDY6Q29tbWl0NzI0NzEyOmU0OTFmMzk5MTQ3YWFmMDlmNjMxODc4ZDAwOTM5NmZjNTQwMGRkZmQ=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/405327635419e22a956dfe8f7caf4817c8ae5e93", + "sha": "405327635419e22a956dfe8f7caf4817c8ae5e93", + "url": "https://api.github.com/repos/rust-lang/rust/commits/405327635419e22a956dfe8f7caf4817c8ae5e93" + } + ], + "sha": "e491f399147aaf09f631878d009396fc5400ddfd", + "url": "https://api.github.com/repos/rust-lang/rust/commits/e491f399147aaf09f631878d009396fc5400ddfd" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/7916e00f2bc343baa665f380084f0b0d8792afa4/comments", + "commit": { + "author": { + "date": "2017-02-07T19:48:16Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2017-02-07T19:48:16Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Bump stable release date", + "tree": { + "sha": "4dfbcc8f3e8a7c2b8d51814647c72a6d03b53508", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/4dfbcc8f3e8a7c2b8d51814647c72a6d03b53508" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/7916e00f2bc343baa665f380084f0b0d8792afa4", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/7916e00f2bc343baa665f380084f0b0d8792afa4", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjc5MTZlMDBmMmJjMzQzYmFhNjY1ZjM4MDA4NGYwYjBkODc5MmFmYTQ=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/c49d10207a7e105525fb3bd71c18fde6fc2f5aed", + "sha": "c49d10207a7e105525fb3bd71c18fde6fc2f5aed", + "url": "https://api.github.com/repos/rust-lang/rust/commits/c49d10207a7e105525fb3bd71c18fde6fc2f5aed" + } + ], + "sha": "7916e00f2bc343baa665f380084f0b0d8792afa4", + "url": "https://api.github.com/repos/rust-lang/rust/commits/7916e00f2bc343baa665f380084f0b0d8792afa4" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/d650cf5c383aeed222e835009c28901c236820e1/comments", + "commit": { + "author": { + "date": "2017-02-04T01:12:38Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2017-02-04T01:12:39Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Update relnotes for 1.15.1\n\nI already checked this into stable, but it needs to be on master/beta too.", + "tree": { + "sha": "6407e6098a1f482d20c90d1f47751a46b833e6bb", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/6407e6098a1f482d20c90d1f47751a46b833e6bb" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/d650cf5c383aeed222e835009c28901c236820e1", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/d650cf5c383aeed222e835009c28901c236820e1", + "node_id": "MDY6Q29tbWl0NzI0NzEyOmQ2NTBjZjVjMzgzYWVlZDIyMmU4MzUwMDljMjg5MDFjMjM2ODIwZTE=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/86d9ed6c82c6745fec46b9ecf2fa91be7924dd16", + "sha": "86d9ed6c82c6745fec46b9ecf2fa91be7924dd16", + "url": "https://api.github.com/repos/rust-lang/rust/commits/86d9ed6c82c6745fec46b9ecf2fa91be7924dd16" + } + ], + "sha": "d650cf5c383aeed222e835009c28901c236820e1", + "url": "https://api.github.com/repos/rust-lang/rust/commits/d650cf5c383aeed222e835009c28901c236820e1" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/a2735c02493d816835a19249dd258e0c678530d0/comments", + "commit": { + "author": { + "date": "2016-10-09T17:30:11Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2017-01-26T22:11:29Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "rustc: Remove all \"consider using an explicit lifetime parameter\" suggestions\n\nThese give so many incorrect suggestions that having them is\ndetrimental to the user experience. The compiler should not be\nsuggesting changes to the code that are wrong - it is infuriating: not\nonly is the compiler telling you that _you don't understand_ borrowing,\n_the compiler itself_ appears to not understand borrowing. It does not\ninspire confidence.", + "tree": { + "sha": "44f0eafe3efebf0ea9ce162a107194d7b7548f5d", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/44f0eafe3efebf0ea9ce162a107194d7b7548f5d" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/a2735c02493d816835a19249dd258e0c678530d0", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/a2735c02493d816835a19249dd258e0c678530d0", + "node_id": "MDY6Q29tbWl0NzI0NzEyOmEyNzM1YzAyNDkzZDgxNjgzNWExOTI0OWRkMjU4ZTBjNjc4NTMwZDA=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/8430042a49bbd49bbb4fbc54f457feb5fb614f56", + "sha": "8430042a49bbd49bbb4fbc54f457feb5fb614f56", + "url": "https://api.github.com/repos/rust-lang/rust/commits/8430042a49bbd49bbb4fbc54f457feb5fb614f56" + } + ], + "sha": "a2735c02493d816835a19249dd258e0c678530d0", + "url": "https://api.github.com/repos/rust-lang/rust/commits/a2735c02493d816835a19249dd258e0c678530d0" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/a0a4af139dcac3c1629e5853d72df27616a00d2a/comments", + "commit": { + "author": { + "date": "2017-01-10T00:44:02Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2017-01-17T22:20:26Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "1.15 release notes", + "tree": { + "sha": "b11a6723da574a502e4ba4155f1589057fcb3bc1", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/b11a6723da574a502e4ba4155f1589057fcb3bc1" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/a0a4af139dcac3c1629e5853d72df27616a00d2a", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/a0a4af139dcac3c1629e5853d72df27616a00d2a", + "node_id": "MDY6Q29tbWl0NzI0NzEyOmEwYTRhZjEzOWRjYWMzYzE2MjllNTg1M2Q3MmRmMjc2MTZhMDBkMmE=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/bd8e9b0c828bce489eb948853a6cf86b69b26799", + "sha": "bd8e9b0c828bce489eb948853a6cf86b69b26799", + "url": "https://api.github.com/repos/rust-lang/rust/commits/bd8e9b0c828bce489eb948853a6cf86b69b26799" + } + ], + "sha": "a0a4af139dcac3c1629e5853d72df27616a00d2a", + "url": "https://api.github.com/repos/rust-lang/rust/commits/a0a4af139dcac3c1629e5853d72df27616a00d2a" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/6207e80d2cc8a870f1b13249dda31a93b7697ffa/comments", + "commit": { + "author": { + "date": "2016-12-20T22:40:46Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2016-12-29T16:47:20Z", + "email": "alex@alexcrichton.com", + "name": "Alex Crichton" + }, + "message": "Bump bootstrap compiler", + "tree": { + "sha": "9686e0fd8f28bc23af286968b54f63240fc43052", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/9686e0fd8f28bc23af286968b54f63240fc43052" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/6207e80d2cc8a870f1b13249dda31a93b7697ffa", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/64996?v=4", + "events_url": "https://api.github.com/users/alexcrichton/events{/privacy}", + "followers_url": "https://api.github.com/users/alexcrichton/followers", + "following_url": "https://api.github.com/users/alexcrichton/following{/other_user}", + "gists_url": "https://api.github.com/users/alexcrichton/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/alexcrichton", + "id": 64996, + "login": "alexcrichton", + "node_id": "MDQ6VXNlcjY0OTk2", + "organizations_url": "https://api.github.com/users/alexcrichton/orgs", + "received_events_url": "https://api.github.com/users/alexcrichton/received_events", + "repos_url": "https://api.github.com/users/alexcrichton/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/alexcrichton/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/alexcrichton/subscriptions", + "type": "User", + "url": "https://api.github.com/users/alexcrichton" + }, + "html_url": "https://github.com/rust-lang/rust/commit/6207e80d2cc8a870f1b13249dda31a93b7697ffa", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjYyMDdlODBkMmNjOGE4NzBmMWIxMzI0OWRkYTMxYTkzYjc2OTdmZmE=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/3f957ebeff8932637002574c9eae75a702b202b7", + "sha": "3f957ebeff8932637002574c9eae75a702b202b7", + "url": "https://api.github.com/repos/rust-lang/rust/commits/3f957ebeff8932637002574c9eae75a702b202b7" + } + ], + "sha": "6207e80d2cc8a870f1b13249dda31a93b7697ffa", + "url": "https://api.github.com/repos/rust-lang/rust/commits/6207e80d2cc8a870f1b13249dda31a93b7697ffa" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/31bda236bd7573482614f86998536ce3b2ba98f5/comments", + "commit": { + "author": { + "date": "2016-12-25T02:09:10Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2016-12-25T02:09:10Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Emscripten targets are Unix targets", + "tree": { + "sha": "9610edec75d482dff11bc275ed241ea5f8cdd77b", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/9610edec75d482dff11bc275ed241ea5f8cdd77b" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/31bda236bd7573482614f86998536ce3b2ba98f5", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/31bda236bd7573482614f86998536ce3b2ba98f5", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjMxYmRhMjM2YmQ3NTczNDgyNjE0Zjg2OTk4NTM2Y2UzYjJiYTk4ZjU=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/e60aa62ffe7462d48cb44ab33f2551b466745e83", + "sha": "e60aa62ffe7462d48cb44ab33f2551b466745e83", + "url": "https://api.github.com/repos/rust-lang/rust/commits/e60aa62ffe7462d48cb44ab33f2551b466745e83" + } + ], + "sha": "31bda236bd7573482614f86998536ce3b2ba98f5", + "url": "https://api.github.com/repos/rust-lang/rust/commits/31bda236bd7573482614f86998536ce3b2ba98f5" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/7d428b71dec973d6f53e16d18af7e2751321aafe/comments", + "commit": { + "author": { + "date": "2016-12-22T22:00:21Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2016-12-22T22:33:42Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Delete the llvm submodule lockfile when configuring on the bots\n\nThis should fix the periodic error that .git/modules/src/llvm/index.lock\nexists on the mac slaves.", + "tree": { + "sha": "870e68eaeb33025b7ec08d6b696ecb22b730489b", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/870e68eaeb33025b7ec08d6b696ecb22b730489b" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/7d428b71dec973d6f53e16d18af7e2751321aafe", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/7d428b71dec973d6f53e16d18af7e2751321aafe", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjdkNDI4YjcxZGVjOTczZDZmNTNlMTZkMThhZjdlMjc1MTMyMWFhZmU=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/17d873c2db77d029b8fe26d57b676e5797e99441", + "sha": "17d873c2db77d029b8fe26d57b676e5797e99441", + "url": "https://api.github.com/repos/rust-lang/rust/commits/17d873c2db77d029b8fe26d57b676e5797e99441" + } + ], + "sha": "7d428b71dec973d6f53e16d18af7e2751321aafe", + "url": "https://api.github.com/repos/rust-lang/rust/commits/7d428b71dec973d6f53e16d18af7e2751321aafe" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/2dc2f5fafb17c5bb406ef2187332ebaf2dd8d35d/comments", + "commit": { + "author": { + "date": "2016-12-19T21:57:43Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2016-12-19T21:57:43Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Bump version to 1.16", + "tree": { + "sha": "f5ec406d7921b5bf601a07093987208daaf03a5f", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/f5ec406d7921b5bf601a07093987208daaf03a5f" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/2dc2f5fafb17c5bb406ef2187332ebaf2dd8d35d", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/2dc2f5fafb17c5bb406ef2187332ebaf2dd8d35d", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjJkYzJmNWZhZmIxN2M1YmI0MDZlZjIxODczMzJlYmFmMmRkOGQzNWQ=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/3f9823d5f53230e83b707b4876b5bb271a4c22ef", + "sha": "3f9823d5f53230e83b707b4876b5bb271a4c22ef", + "url": "https://api.github.com/repos/rust-lang/rust/commits/3f9823d5f53230e83b707b4876b5bb271a4c22ef" + } + ], + "sha": "2dc2f5fafb17c5bb406ef2187332ebaf2dd8d35d", + "url": "https://api.github.com/repos/rust-lang/rust/commits/2dc2f5fafb17c5bb406ef2187332ebaf2dd8d35d" + }, + { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/2afadaadc99118b169d2c3aec01e9814409b37fa/comments", + "commit": { + "author": { + "date": "2016-12-17T22:59:39Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "comment_count": 0, + "committer": { + "date": "2016-12-17T23:02:35Z", + "email": "banderson@mozilla.com", + "name": "Brian Anderson" + }, + "message": "Edits. More platform support", + "tree": { + "sha": "4133357897c81c40ab8faf4882851ef78161b9e2", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/4133357897c81c40ab8faf4882851ef78161b9e2" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/2afadaadc99118b169d2c3aec01e9814409b37fa", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/147214?v=4", + "events_url": "https://api.github.com/users/brson/events{/privacy}", + "followers_url": "https://api.github.com/users/brson/followers", + "following_url": "https://api.github.com/users/brson/following{/other_user}", + "gists_url": "https://api.github.com/users/brson/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/brson", + "id": 147214, + "login": "brson", + "node_id": "MDQ6VXNlcjE0NzIxNA==", + "organizations_url": "https://api.github.com/users/brson/orgs", + "received_events_url": "https://api.github.com/users/brson/received_events", + "repos_url": "https://api.github.com/users/brson/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/brson/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/brson/subscriptions", + "type": "User", + "url": "https://api.github.com/users/brson" + }, + "html_url": "https://github.com/rust-lang/rust/commit/2afadaadc99118b169d2c3aec01e9814409b37fa", + "node_id": "MDY6Q29tbWl0NzI0NzEyOjJhZmFkYWFkYzk5MTE4YjE2OWQyYzNhZWMwMWU5ODE0NDA5YjM3ZmE=", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/09a9859c0004a3a442ad46b517110568df3e0c35", + "sha": "09a9859c0004a3a442ad46b517110568df3e0c35", + "url": "https://api.github.com/repos/rust-lang/rust/commits/09a9859c0004a3a442ad46b517110568df3e0c35" + } + ], + "sha": "2afadaadc99118b169d2c3aec01e9814409b37fa", + "url": "https://api.github.com/repos/rust-lang/rust/commits/2afadaadc99118b169d2c3aec01e9814409b37fa" + } + ] +} diff --git a/tests/github_client/issue_properties/00-GET-repos_rust-lang_rust.json b/tests/github_client/issue_properties/00-GET-repos_rust-lang_rust.json new file mode 100644 index 00000000..3589a6e8 --- /dev/null +++ b/tests/github_client/issue_properties/00-GET-repos_rust-lang_rust.json @@ -0,0 +1,160 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": false, + "allow_squash_merge": false, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "delete_branch_on_merge": true, + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10326, + "forks_count": 10326, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "network_count": 10326, + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9513, + "open_issues_count": 9513, + "organization": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "permissions": { + "admin": false, + "maintain": false, + "pull": true, + "push": true, + "triage": true + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T18:16:26Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066392, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77402, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_count": 1487, + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "temp_clone_token": "", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T19:09:47Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 77402, + "watchers_count": 77402, + "web_commit_signoff_required": false + } +} diff --git a/tests/github_client/issue_properties/01-GET-repos_rust-lang_rust_issues.json b/tests/github_client/issue_properties/01-GET-repos_rust-lang_rust_issues.json new file mode 100644 index 00000000..d0a8d7d1 --- /dev/null +++ b/tests/github_client/issue_properties/01-GET-repos_rust-lang_rust_issues.json @@ -0,0 +1,431 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust/issues", + "query": "labels=A-coherence&filter=all&sort=created&direction=asc&per_page=100", + "request_body": "", + "response_code": 200, + "response_body": [ + { + "active_lock_reason": null, + "assignee": { + "avatar_url": "https://avatars.githubusercontent.com/u/16256974?v=4", + "events_url": "https://api.github.com/users/atsuzaki/events{/privacy}", + "followers_url": "https://api.github.com/users/atsuzaki/followers", + "following_url": "https://api.github.com/users/atsuzaki/following{/other_user}", + "gists_url": "https://api.github.com/users/atsuzaki/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/atsuzaki", + "id": 16256974, + "login": "atsuzaki", + "node_id": "MDQ6VXNlcjE2MjU2OTc0", + "organizations_url": "https://api.github.com/users/atsuzaki/orgs", + "received_events_url": "https://api.github.com/users/atsuzaki/received_events", + "repos_url": "https://api.github.com/users/atsuzaki/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/atsuzaki/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/atsuzaki/subscriptions", + "type": "User", + "url": "https://api.github.com/users/atsuzaki" + }, + "assignees": [ + { + "avatar_url": "https://avatars.githubusercontent.com/u/16256974?v=4", + "events_url": "https://api.github.com/users/atsuzaki/events{/privacy}", + "followers_url": "https://api.github.com/users/atsuzaki/followers", + "following_url": "https://api.github.com/users/atsuzaki/following{/other_user}", + "gists_url": "https://api.github.com/users/atsuzaki/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/atsuzaki", + "id": 16256974, + "login": "atsuzaki", + "node_id": "MDQ6VXNlcjE2MjU2OTc0", + "organizations_url": "https://api.github.com/users/atsuzaki/orgs", + "received_events_url": "https://api.github.com/users/atsuzaki/received_events", + "repos_url": "https://api.github.com/users/atsuzaki/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/atsuzaki/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/atsuzaki/subscriptions", + "type": "User", + "url": "https://api.github.com/users/atsuzaki" + } + ], + "author_association": "MEMBER", + "body": "We consider projections to be foreign types during orphan check\n\nhttps://github.com/rust-lang/rust/blob/ceeb5ade201e4181c6d5df2ba96ae5fb2193aadc/compiler/rustc_trait_selection/src/traits/coherence.rs#L731\n\nbut do not consider them to be parameters when checking for uncovered types https://github.com/rust-lang/rust/blob/ceeb5ade201e4181c6d5df2ba96ae5fb2193aadc/compiler/rustc_trait_selection/src/traits/coherence.rs#L621\n\nThis is more obvious after #99552\n\nthis means that the following impl passes the orphan check even though it shouldn't\n```rust\n// crate a\npub trait Foreign {\n type Assoc;\n}\n\n// crate b\nuse a::Foreign;\n\ntrait Id {\n type Assoc;\n}\n\nimpl Id for T {\n type Assoc = T;\n}\n\npub struct B;\nimpl Foreign for ::Assoc {\n type Assoc = usize;\n}\n```\nThe impl in `b` overlaps with an impl `impl Foreign for LocalTy` in another crate `c` which passes the orphan check.\n\nWhile I wasn't able to cause runtime UB with this, I was able to get an ICE during `codegen_fulfill_obligation`: https://github.com/lcnr/orphan-check-ub\n\ncc @rust-lang/types \n\n\n\n\n\n\n\n\n", + "closed_at": null, + "comments": 5, + "comments_url": "https://api.github.com/repos/rust-lang/rust/issues/99554/comments", + "created_at": "2022-07-21T10:56:00Z", + "events_url": "https://api.github.com/repos/rust-lang/rust/issues/99554/events", + "html_url": "https://github.com/rust-lang/rust/issues/99554", + "id": 1313070635, + "labels": [ + { + "color": "f7e101", + "default": false, + "description": "Area: Trait system", + "id": 13836860, + "name": "A-traits", + "node_id": "MDU6TGFiZWwxMzgzNjg2MA==", + "url": "https://api.github.com/repos/rust-lang/rust/labels/A-traits" + }, + { + "color": "02E10C", + "default": false, + "description": "Call for participation: This issue has a mentor. Use RustcContributor::new on Zulip for discussion.", + "id": 67766349, + "name": "E-mentor", + "node_id": "MDU6TGFiZWw2Nzc2NjM0OQ==", + "url": "https://api.github.com/repos/rust-lang/rust/labels/E-mentor" + }, + { + "color": "f7e101", + "default": false, + "description": "Area: Associated items such as associated types and consts.", + "id": 149689562, + "name": "A-associated-items", + "node_id": "MDU6TGFiZWwxNDk2ODk1NjI=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/A-associated-items" + }, + { + "color": "eb6420", + "default": false, + "description": "High priority", + "id": 203429200, + "name": "P-high", + "node_id": "MDU6TGFiZWwyMDM0MjkyMDA=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/P-high" + }, + { + "color": "e11d21", + "default": false, + "description": "Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness", + "id": 267612997, + "name": "I-unsound", + "node_id": "MDU6TGFiZWwyNjc2MTI5OTc=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/I-unsound" + }, + { + "color": "02e10c", + "default": false, + "description": "Call for participation: Experience needed to fix: Medium / intermediate", + "id": 419557634, + "name": "E-medium", + "node_id": "MDU6TGFiZWw0MTk1NTc2MzQ=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/E-medium" + }, + { + "color": "f5f1fd", + "default": false, + "description": "Category: This is a bug.", + "id": 650731663, + "name": "C-bug", + "node_id": "MDU6TGFiZWw2NTA3MzE2NjM=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/C-bug" + }, + { + "color": "bfd4f2", + "default": false, + "description": "Relevant to the types team, which will review and decide on the PR/issue.", + "id": 4172483496, + "name": "T-types", + "node_id": "LA_kwDOAAsO6M74swuo", + "url": "https://api.github.com/repos/rust-lang/rust/labels/T-types" + }, + { + "color": "f7e101", + "default": false, + "description": "Area: Coherence", + "id": 4917350639, + "name": "A-coherence", + "node_id": "LA_kwDOAAsO6M8AAAABJRjQ7w", + "url": "https://api.github.com/repos/rust-lang/rust/labels/A-coherence" + } + ], + "labels_url": "https://api.github.com/repos/rust-lang/rust/issues/99554/labels{/name}", + "locked": false, + "milestone": null, + "node_id": "I_kwDOAAsO6M5OQ94r", + "number": 99554, + "performed_via_github_app": null, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/rust-lang/rust/issues/99554/reactions" + }, + "repository_url": "https://api.github.com/repos/rust-lang/rust", + "state": "open", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/rust-lang/rust/issues/99554/timeline", + "title": "orphan check incorrectly handles projections", + "updated_at": "2023-01-27T17:08:45Z", + "url": "https://api.github.com/repos/rust-lang/rust/issues/99554", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/29864074?v=4", + "events_url": "https://api.github.com/users/lcnr/events{/privacy}", + "followers_url": "https://api.github.com/users/lcnr/followers", + "following_url": "https://api.github.com/users/lcnr/following{/other_user}", + "gists_url": "https://api.github.com/users/lcnr/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/lcnr", + "id": 29864074, + "login": "lcnr", + "node_id": "MDQ6VXNlcjI5ODY0MDc0", + "organizations_url": "https://api.github.com/users/lcnr/orgs", + "received_events_url": "https://api.github.com/users/lcnr/received_events", + "repos_url": "https://api.github.com/users/lcnr/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/lcnr/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/lcnr/subscriptions", + "type": "User", + "url": "https://api.github.com/users/lcnr" + } + }, + { + "active_lock_reason": null, + "assignee": null, + "assignees": [], + "author_association": "MEMBER", + "body": "which is unsound during coherence, as coherence requires completeness\r\n```rust\r\n#![feature(specialization)]\r\n\r\ntrait Default {\r\n type Id;\r\n}\r\n\r\nimpl Default for T {\r\n default type Id = T;\r\n}\r\n\r\ntrait Overlap {\r\n type Assoc;\r\n}\r\n\r\nimpl Overlap for u32 {\r\n type Assoc = usize;\r\n}\r\n\r\nimpl Overlap for ::Id {\r\n type Assoc = Box;\r\n}\r\n```\r\n\r\nhttps://github.com/rust-lang/rust/blob/03770f0e2b60c02db8fcf52fed5fb36aac70cedc/compiler/rustc_trait_selection/src/traits/project.rs#L1526", + "closed_at": null, + "comments": 0, + "comments_url": "https://api.github.com/repos/rust-lang/rust/issues/105782/comments", + "created_at": "2022-12-16T15:11:15Z", + "events_url": "https://api.github.com/repos/rust-lang/rust/issues/105782/events", + "html_url": "https://github.com/rust-lang/rust/issues/105782", + "id": 1500394507, + "labels": [ + { + "color": "f7e101", + "default": false, + "description": "Area: Trait system", + "id": 13836860, + "name": "A-traits", + "node_id": "MDU6TGFiZWwxMzgzNjg2MA==", + "url": "https://api.github.com/repos/rust-lang/rust/labels/A-traits" + }, + { + "color": "e11d21", + "default": false, + "description": "Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness", + "id": 267612997, + "name": "I-unsound", + "node_id": "MDU6TGFiZWwyNjc2MTI5OTc=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/I-unsound" + }, + { + "color": "f7e101", + "default": false, + "description": "Area: Trait impl specialization", + "id": 347795552, + "name": "A-specialization", + "node_id": "MDU6TGFiZWwzNDc3OTU1NTI=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/A-specialization" + }, + { + "color": "f5f1fd", + "default": false, + "description": "Category: This is a bug.", + "id": 650731663, + "name": "C-bug", + "node_id": "MDU6TGFiZWw2NTA3MzE2NjM=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/C-bug" + }, + { + "color": "76dcde", + "default": false, + "description": "This issue requires a nightly compiler in some way.", + "id": 1472563007, + "name": "requires-nightly", + "node_id": "MDU6TGFiZWwxNDcyNTYzMDA3", + "url": "https://api.github.com/repos/rust-lang/rust/labels/requires-nightly" + }, + { + "color": "f9c0cc", + "default": false, + "description": "`#![feature(specialization)]`", + "id": 1472579062, + "name": "F-specialization", + "node_id": "MDU6TGFiZWwxNDcyNTc5MDYy", + "url": "https://api.github.com/repos/rust-lang/rust/labels/F-specialization" + }, + { + "color": "f7e101", + "default": false, + "description": "Area: Coherence", + "id": 4917350639, + "name": "A-coherence", + "node_id": "LA_kwDOAAsO6M8AAAABJRjQ7w", + "url": "https://api.github.com/repos/rust-lang/rust/labels/A-coherence" + } + ], + "labels_url": "https://api.github.com/repos/rust-lang/rust/issues/105782/labels{/name}", + "locked": false, + "milestone": null, + "node_id": "I_kwDOAAsO6M5ZbjQL", + "number": 105782, + "performed_via_github_app": null, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/rust-lang/rust/issues/105782/reactions" + }, + "repository_url": "https://api.github.com/repos/rust-lang/rust", + "state": "open", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/rust-lang/rust/issues/105782/timeline", + "title": "specialization: default items completely drop candidates instead of ambiguity", + "updated_at": "2022-12-16T16:17:41Z", + "url": "https://api.github.com/repos/rust-lang/rust/issues/105782", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/29864074?v=4", + "events_url": "https://api.github.com/users/lcnr/events{/privacy}", + "followers_url": "https://api.github.com/users/lcnr/followers", + "following_url": "https://api.github.com/users/lcnr/following{/other_user}", + "gists_url": "https://api.github.com/users/lcnr/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/lcnr", + "id": 29864074, + "login": "lcnr", + "node_id": "MDQ6VXNlcjI5ODY0MDc0", + "organizations_url": "https://api.github.com/users/lcnr/orgs", + "received_events_url": "https://api.github.com/users/lcnr/received_events", + "repos_url": "https://api.github.com/users/lcnr/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/lcnr/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/lcnr/subscriptions", + "type": "User", + "url": "https://api.github.com/users/lcnr" + } + }, + { + "active_lock_reason": null, + "assignee": null, + "assignees": [], + "author_association": "MEMBER", + "body": "```rust\r\n// Using the higher ranked projection hack to prevent us from replacing the projection\r\n// with an inference variable.\r\ntrait ToUnit<'a> {\r\n type Unit;\r\n}\r\n\r\nstruct LocalTy;\r\nimpl<'a> ToUnit<'a> for *const LocalTy {\r\n type Unit = ();\r\n}\r\n\r\nimpl<'a, T: Copy + ?Sized> ToUnit<'a> for *const T {\r\n type Unit = ();\r\n}\r\n\r\ntrait Overlap {\r\n type Assoc;\r\n}\r\n\r\ntype Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit;\r\n\r\nimpl Overlap for T {\r\n type Assoc = usize;\r\n}\r\n\r\nimpl Overlap fn(&'a (), Assoc<'a, T>)> for T\r\nwhere\r\n for<'a> *const T: ToUnit<'a>,\r\n{\r\n type Assoc = Box;\r\n}\r\n\r\nfn foo, U>(x: T::Assoc) -> T::Assoc {\r\n x\r\n}\r\n\r\nfn main() {\r\n foo:: fn(&'a (), ()), for<'a> fn(&'a (), ())>(3usize);\r\n}\r\n```\r\n\r\n`for<'a> fn(&'a (), ())>: Overlap fn(&'a (), ())>>` can be satisfied using both impls, ignoring a deficiency of the current normalization routine which means that right now the second impl pretty much never applies.\r\n\r\nCurrently inference constraints from equating the self type are not used to normalize the trait argument so we fail when equating `()` with `Assoc<'a, for<'a> fn(&'a (), ())>` even those these two are the same type. This will change once deferred projection equality is implemented.\r\n\r\n## why this currently passes coherence\r\n\r\nCoherence does a pairwise check for all relevant impls. It starts by instantiating the impl parameters with inference vars and equating the impl headers. When we do that with `Overlap for T` and `Overlap fn(&'a (), Assoc<'a, T>)> for T` we have:\r\n\r\n- `eq(?0: Overflap, ?1: Overlap fn(&'a (), <*const ?1 as ToUnit<'a>>::Unit)>)`\r\n - `eq(?0, ?1)` constrains `?1` to be equal to `?0`\r\n - `eq(?0, for<'a> fn(&'a (), <*const ?0 as ToUnit<'a>>::Unit)>)`: this now fails the occurs check\r\n\r\nThe occurs check is necessary to prevent ourselves from creating infinitely large types, e.g. `?0 = Vec`. But it does mean that coherence considers these two impls to be disjoint. Because the inference var only occurs inside of a projection, there's a way to equate these two types without resulting in an infinitely large type by normalizing the projection.", + "closed_at": null, + "comments": 1, + "comments_url": "https://api.github.com/repos/rust-lang/rust/issues/105787/comments", + "created_at": "2022-12-16T16:16:11Z", + "events_url": "https://api.github.com/repos/rust-lang/rust/issues/105787/events", + "html_url": "https://github.com/rust-lang/rust/issues/105787", + "id": 1500501670, + "labels": [ + { + "color": "f7e101", + "default": false, + "description": "Area: Trait system", + "id": 13836860, + "name": "A-traits", + "node_id": "MDU6TGFiZWwxMzgzNjg2MA==", + "url": "https://api.github.com/repos/rust-lang/rust/labels/A-traits" + }, + { + "color": "eb6420", + "default": false, + "description": "Medium priority", + "id": 60344715, + "name": "P-medium", + "node_id": "MDU6TGFiZWw2MDM0NDcxNQ==", + "url": "https://api.github.com/repos/rust-lang/rust/labels/P-medium" + }, + { + "color": "e11d21", + "default": false, + "description": "Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness", + "id": 267612997, + "name": "I-unsound", + "node_id": "MDU6TGFiZWwyNjc2MTI5OTc=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/I-unsound" + }, + { + "color": "f5f1fd", + "default": false, + "description": "Category: This is a bug.", + "id": 650731663, + "name": "C-bug", + "node_id": "MDU6TGFiZWw2NTA3MzE2NjM=", + "url": "https://api.github.com/repos/rust-lang/rust/labels/C-bug" + }, + { + "color": "bfd4f2", + "default": false, + "description": "Relevant to the types team, which will review and decide on the PR/issue.", + "id": 4172483496, + "name": "T-types", + "node_id": "LA_kwDOAAsO6M74swuo", + "url": "https://api.github.com/repos/rust-lang/rust/labels/T-types" + }, + { + "color": "f7e101", + "default": false, + "description": "Area: Coherence", + "id": 4917350639, + "name": "A-coherence", + "node_id": "LA_kwDOAAsO6M8AAAABJRjQ7w", + "url": "https://api.github.com/repos/rust-lang/rust/labels/A-coherence" + } + ], + "labels_url": "https://api.github.com/repos/rust-lang/rust/issues/105787/labels{/name}", + "locked": false, + "milestone": null, + "node_id": "I_kwDOAAsO6M5Zb9am", + "number": 105787, + "performed_via_github_app": null, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/rust-lang/rust/issues/105787/reactions" + }, + "repository_url": "https://api.github.com/repos/rust-lang/rust", + "state": "open", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/rust-lang/rust/issues/105787/timeline", + "title": "occurs check with projections results in error, not ambiguity", + "updated_at": "2022-12-17T05:07:04Z", + "url": "https://api.github.com/repos/rust-lang/rust/issues/105787", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/29864074?v=4", + "events_url": "https://api.github.com/users/lcnr/events{/privacy}", + "followers_url": "https://api.github.com/users/lcnr/followers", + "following_url": "https://api.github.com/users/lcnr/following{/other_user}", + "gists_url": "https://api.github.com/users/lcnr/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/lcnr", + "id": 29864074, + "login": "lcnr", + "node_id": "MDQ6VXNlcjI5ODY0MDc0", + "organizations_url": "https://api.github.com/users/lcnr/orgs", + "received_events_url": "https://api.github.com/users/lcnr/received_events", + "repos_url": "https://api.github.com/users/lcnr/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/lcnr/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/lcnr/subscriptions", + "type": "User", + "url": "https://api.github.com/users/lcnr" + } + } + ] +} diff --git a/tests/github_client/merge_upstream/00-GET-repos_ehuss_rust.json b/tests/github_client/merge_upstream/00-GET-repos_ehuss_rust.json new file mode 100644 index 00000000..4c39a6ef --- /dev/null +++ b/tests/github_client/merge_upstream/00-GET-repos_ehuss_rust.json @@ -0,0 +1,365 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/ehuss/rust", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/rust/branches{/branch}", + "clone_url": "https://github.com/ehuss/rust.git", + "collaborators_url": "https://api.github.com/repos/ehuss/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/rust/contributors", + "created_at": "2018-01-14T20:35:48Z", + "default_branch": "master", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/rust/deployments", + "description": "A safe, concurrent, practical language.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/rust/downloads", + "events_url": "https://api.github.com/repos/ehuss/rust/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/ehuss/rust/forks", + "full_name": "ehuss/rust", + "git_commits_url": "https://api.github.com/repos/ehuss/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/rust/git/tags{/sha}", + "git_url": "git://github.com/ehuss/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": false, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/ehuss/rust/hooks", + "html_url": "https://github.com/ehuss/rust", + "id": 117464625, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/ehuss/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/rust/merges", + "milestones_url": "https://api.github.com/repos/ehuss/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "network_count": 10326, + "node_id": "MDEwOlJlcG9zaXRvcnkxMTc0NjQ2MjU=", + "notifications_url": "https://api.github.com/repos/ehuss/rust/notifications{?since,all,participating}", + "open_issues": 0, + "open_issues_count": 0, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "parent": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10326, + "forks_count": 10326, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9513, + "open_issues_count": 9513, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T18:16:26Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066392, + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77402, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T19:09:47Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "visibility": "public", + "watchers": 77402, + "watchers_count": 77402, + "web_commit_signoff_required": false + }, + "permissions": { + "admin": true, + "maintain": true, + "pull": true, + "push": true, + "triage": true + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/rust/pulls{/number}", + "pushed_at": "2023-02-05T19:24:47Z", + "releases_url": "https://api.github.com/repos/ehuss/rust/releases{/id}", + "security_and_analysis": { + "secret_scanning": { + "status": "disabled" + }, + "secret_scanning_push_protection": { + "status": "disabled" + } + }, + "size": 1054343, + "source": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10326, + "forks_count": 10326, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9513, + "open_issues_count": 9513, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T18:16:26Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066392, + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77402, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T19:09:47Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "visibility": "public", + "watchers": 77402, + "watchers_count": 77402, + "web_commit_signoff_required": false + }, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/rust.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/rust/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/rust/statuses/{sha}", + "subscribers_count": 0, + "subscribers_url": "https://api.github.com/repos/ehuss/rust/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/rust/subscription", + "svn_url": "https://github.com/ehuss/rust", + "tags_url": "https://api.github.com/repos/ehuss/rust/tags", + "teams_url": "https://api.github.com/repos/ehuss/rust/teams", + "temp_clone_token": "", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/rust/git/trees{/sha}", + "updated_at": "2021-11-03T23:44:04Z", + "url": "https://api.github.com/repos/ehuss/rust", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + } +} diff --git a/tests/github_client/merge_upstream/01-POST-repos_ehuss_rust_merge-upstream.json b/tests/github_client/merge_upstream/01-POST-repos_ehuss_rust_merge-upstream.json new file mode 100644 index 00000000..ebd5cb67 --- /dev/null +++ b/tests/github_client/merge_upstream/01-POST-repos_ehuss_rust_merge-upstream.json @@ -0,0 +1,13 @@ +{ + "kind": "Request", + "method": "POST", + "path": "/repos/ehuss/rust/merge-upstream", + "query": null, + "request_body": "{\"branch\":\"docs-update\"}", + "response_code": 200, + "response_body": { + "base_branch": "rust-lang:master", + "merge_type": "fast-forward", + "message": "Successfully fetched and fast-forwarded from upstream rust-lang:master." + } +} diff --git a/tests/github_client/mod.rs b/tests/github_client/mod.rs new file mode 100644 index 00000000..a80461b7 --- /dev/null +++ b/tests/github_client/mod.rs @@ -0,0 +1,477 @@ +//! `GithubClient` tests. +//! +//! These tests exercise the behavior of `GithubClient`. They involve setting +//! up HTTP servers, creating a `GithubClient` to connect to those servers, +//! executing some action, and validating the result. +//! +//! The [`run_test`] function is used to set up the test and give you a +//! [`GithubClient`] to perform some action and validate its result. +//! +//! To write one of these tests, you'll need to use the recording function +//! against the live GitHub site to fetch what the actual JSON objects should +//! look like. To write a test, follow these steps: +//! +//! 1. Create a test following the form of the other tests where inside +//! the `run_test` callback, execute the function you want to exercise. +//! +//! 2. Run just a single test with recording enabled: +//! +//! ```sh +//! TODO +//! TRIAGEBOT_TEST_RECORD=github_client/TEST_NAME_HERE cargo test \ +//! --test testsuite -- --exact github_client::TEST_NAME_HERE +//! ``` +//! +//! Replace TEST_NAME_HERE with the name of your test. This will run the +//! command against the live site and store the JSON in a directory with +//! the given TEST_NAME_HERE. +//! +//! 3. Add some asserts to the result of the return value from the function. +//! +//! 4. Do a final test to make sure everything is working: +//! ```sh +//! cargo test --test testsuite -- --exact github_client::TEST_NAME_HERE +//! ``` +//! +//! **WARNING**: Do not write tests that modify the rust-lang org repos like +//! rust-lang/rust. Write those tests against your own fork (like +//! `ehuss/rust`). We don't want to pollute the real repos with things like +//! test PRs. + +use super::{HttpServer, HttpServerHandle}; +use futures::Future; +use std::sync::mpsc; +use std::time::Duration; +use triagebot::github::GithubClient; +use triagebot::test_record::{self, Activity}; + +/// A context used for running a test. +struct GhTestCtx { + gh: GithubClient, + #[allow(dead_code)] // held for drop + server: HttpServerHandle, +} + +/// Checks that the server didn't generate any errors, and that it finished +/// processing all recorded events. +fn assert_no_error(hook_recv: &mpsc::Receiver) { + if test_record::is_recording() { + return; + } + loop { + let activity = hook_recv.recv_timeout(Duration::new(60, 0)).unwrap(); + match activity { + Activity::Error { message } => { + panic!("unexpected server error: {message}"); + } + Activity::Finished => { + break; + } + a => panic!("unexpected activity {a:?}"), + } + } +} + +fn build(test_name: &str) -> GhTestCtx { + crate::assert_single_record(); + crate::maybe_enable_logging(); + triagebot::test_record::init().unwrap(); + if test_record::is_recording() { + // While recording, there are no activities to load. + // Point the GithubClient to the real site. + dotenv::dotenv().ok(); + let gh = GithubClient::new_from_env(); + // The server is unused, but needed for the context. + let server = HttpServer::new(Vec::new()); + return GhTestCtx { gh, server }; + } + + let activities = crate::load_activities("tests/github_client", test_name); + let server = HttpServer::new(activities); + let gh = GithubClient::new( + "sekrit-token".to_string(), + format!("http://{}", server.addr), + format!("http://{}/graphql", server.addr), + format!("http://{}", server.addr), + ); + GhTestCtx { gh, server } +} + +/// The main entry point for a test. +/// +/// Pass the name of the test as the first parameter. +fn run_test(name: &str, f: F) +where + F: Fn(GithubClient) -> Fut + Send + Sync, + Fut: Future + Send, +{ + let ctx = build(name); + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap() + .block_on(async { f(ctx.gh).await }); + assert_no_error(&ctx.server.hook_recv); +} + +#[test] +fn repository() { + run_test("repository", |gh| async move { + let repo = gh.repository("rust-lang/rust").await.unwrap(); + assert_eq!(repo.full_name, "rust-lang/rust"); + assert_eq!(repo.default_branch, "master"); + assert_eq!(repo.fork, false); + assert_eq!(repo.owner(), "rust-lang"); + assert_eq!(repo.name(), "rust"); + }); +} + +#[test] +fn is_new_contributor() { + run_test("is_new_contributor", |gh| async move { + let repo = gh.repository("rust-lang/rust").await.unwrap(); + assert_eq!(gh.is_new_contributor(&repo, "octocat").await, true); + assert_eq!(gh.is_new_contributor(&repo, "brson").await, false); + }); +} + +#[test] +fn bors_commits() { + run_test("bors_commits", |gh| async move { + let commits = gh.bors_commits().await; + assert_eq!(commits.len(), 30); + assert_eq!(commits[0].sha, "7f97aeaf73047268299ab55288b3dd886130be47"); + assert_eq!( + commits[0].commit.author.date.to_string(), + "2023-02-05 11:10:11 +00:00" + ); + assert!(commits[0].commit.message.starts_with( + "Auto merge of #107679 - est31:less_import_overhead, r=compiler-errors\n\n\ + Less import overhead for errors\n\n" + )); + assert_eq!( + commits[0].commit.tree.sha, + "28ef3869cb8034a8ab5e4ad389c139ec7dbd6df1" + ); + assert_eq!(commits[0].parents.len(), 2); + assert_eq!( + commits[0].parents[0].sha, + "2a6ff729233c62d1d991da5ed4d01aa29e59d637" + ); + assert_eq!( + commits[0].parents[1].sha, + "580cc89e9c36a89d3cc13a352c96f874eaa76581" + ); + }); +} + +#[test] +fn rust_commit() { + run_test("rust_commit", |gh| async move { + let commit = gh + .rust_commit("7632db0e87d8adccc9a83a47795c9411b1455855") + .await + .unwrap(); + assert_eq!(commit.sha, "7632db0e87d8adccc9a83a47795c9411b1455855"); + assert_eq!( + commit.commit.author.date.to_string(), + "2022-12-08 07:46:42 +00:00" + ); + assert_eq!(commit.commit.message, "Auto merge of #105415 - nikic:update-llvm-10, r=cuviper\n\nUpdate LLVM submodule\n\nThis is a rebase to LLVM 15.0.6.\n\nFixes #103380.\nFixes #104099."); + assert_eq!(commit.parents.len(), 2); + assert_eq!( + commit.parents[0].sha, + "f5418b09e84883c4de2e652a147ab9faff4eee29" + ); + assert_eq!( + commit.parents[1].sha, + "530a687a4bb0bd0e8ab7b3f7d80f2c773be120ef" + ); + }); +} + +#[test] +fn raw_file() { + run_test("raw_file", |gh| async move { + let contents = + b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n".repeat(1000); + let body = gh + .raw_file("ehuss/triagebot-test", "raw-file", "docs/example.txt") + .await + .unwrap() + .unwrap(); + assert_eq!(body, contents); + }); +} + +#[test] +fn git_commit() { + run_test("git_commit", |gh| async move { + let repo = gh.repository("rust-lang/rust").await.unwrap(); + let commit = repo + .git_commit(&gh, "109cccbe4f345c0f0785ce860788580c3e2a29f5") + .await + .unwrap(); + assert_eq!(commit.sha, "109cccbe4f345c0f0785ce860788580c3e2a29f5"); + assert_eq!(commit.author.date.to_string(), "2022-12-13 07:10:53 +00:00"); + assert_eq!(commit.message, "Auto merge of #105350 - compiler-errors:faster-binder-relate, r=oli-obk\n\nFast-path some binder relations\n\nA simpler approach than #104598\n\nFixes #104583\n\nr? types"); + assert_eq!(commit.tree.sha, "e67d87c61892169977204cc2e3fd89b2a19e13bb"); + }); +} + +#[test] +fn update_tree() { + run_test("update_tree", |gh| async move { + let repo = gh.repository("ehuss/rust").await.unwrap(); + let entries = vec![triagebot::github::GitTreeEntry { + path: "src/doc/reference".to_string(), + mode: "160000".to_string(), + object_type: "commit".to_string(), + sha: Some(Some("b9ccb0960e5e98154020d4c02a09cc3901bc2500".to_string())), + content: None, + }]; + let tree = repo + .update_tree(&gh, "6ebac807802fa2458d2f47c2c12fb1e62944e764", &entries) + .await + .unwrap(); + assert_eq!(tree.sha, "45aae523b087e418f2778d4557489de38fede6a3"); + }); +} + +#[test] +fn create_commit() { + run_test("create_commit", |gh| async move { + let repo = gh.repository("ehuss/rust").await.unwrap(); + let commit = repo + .create_commit( + &gh, + "test reference commit", + &["319b88c463fe6f51bb6badbbd3bb97252a60f3a5"], + "45aae523b087e418f2778d4557489de38fede6a3", + ) + .await + .unwrap(); + assert_eq!(commit.sha, "88a426017fa4635ba42203c3b1d1c19f6a028184"); + assert_eq!(commit.author.date.to_string(), "2023-02-05 19:08:57 +00:00"); + assert_eq!(commit.message, "test reference commit"); + assert_eq!(commit.tree.sha, "45aae523b087e418f2778d4557489de38fede6a3"); + }); +} + +#[test] +fn get_reference() { + run_test("get_reference", |gh| async move { + let repo = gh.repository("rust-lang/rust").await.unwrap(); + let git_ref = repo.get_reference(&gh, "heads/stable").await.unwrap(); + assert_eq!(git_ref.refname, "refs/heads/stable"); + assert_eq!(git_ref.object.object_type, "commit"); + assert_eq!( + git_ref.object.sha, + "fc594f15669680fa70d255faec3ca3fb507c3405" + ); + assert_eq!(git_ref.object.url, "https://api.github.com/repos/rust-lang/rust/git/commits/fc594f15669680fa70d255faec3ca3fb507c3405"); + }); +} + +#[test] +fn update_reference() { + run_test("update_reference", |gh| async move { + let repo = gh.repository("ehuss/rust").await.unwrap(); + repo.update_reference( + &gh, + "heads/docs-update", + "88a426017fa4635ba42203c3b1d1c19f6a028184", + ) + .await + .unwrap(); + }); +} + +#[test] +fn submodule() { + run_test("submodule", |gh| async move { + let repo = gh.repository("rust-lang/rust").await.unwrap(); + let submodule = repo + .submodule(&gh, "src/doc/reference", None) + .await + .unwrap(); + assert_eq!(submodule.name, "reference"); + assert_eq!(submodule.path, "src/doc/reference"); + assert_eq!(submodule.sha, "22882fb3f7b4d69fdc0d1731e8b9cfcb6910537d"); + assert_eq!( + submodule.submodule_git_url, + "https://github.com/rust-lang/reference.git" + ); + let sub_repo = submodule.repository(&gh).await.unwrap(); + assert_eq!(sub_repo.full_name, "rust-lang/reference"); + assert_eq!(sub_repo.default_branch, "master"); + assert_eq!(sub_repo.fork, false); + }); +} + +#[test] +fn new_pr() { + run_test("new_pr", |gh| async move { + let repo = gh.repository("ehuss/rust").await.unwrap(); + let issue = repo + .new_pr( + &gh, + "example title", + "ehuss:docs-update", + "master", + "example body text", + ) + .await + .unwrap(); + assert_eq!(issue.number, 7); + assert_eq!(issue.body, "example body text"); + assert_eq!(issue.created_at.to_string(), "2023-02-05 19:20:58 UTC"); + assert_eq!(issue.updated_at.to_string(), "2023-02-05 19:20:58 UTC"); + assert_eq!(issue.merge_commit_sha, None); + assert_eq!(issue.title, "example title"); + assert_eq!(issue.html_url, "https://github.com/ehuss/rust/pull/7"); + assert_eq!(issue.user.login, "ehuss"); + assert_eq!(issue.user.id, Some(43198)); + assert_eq!(issue.labels, vec![]); + assert_eq!(issue.assignees, vec![]); + assert!(matches!( + issue.pull_request, + Some(triagebot::github::PullRequestDetails {}) + )); + assert_eq!(issue.merged, false); + assert_eq!(issue.draft, false); + assert_eq!(issue.base.as_ref().unwrap().git_ref, "master"); + assert_eq!(issue.base.as_ref().unwrap().repo.full_name, "ehuss/rust"); + assert_eq!(issue.head.unwrap().git_ref, "docs-update"); + assert_eq!(issue.state, triagebot::github::IssueState::Open); + }); +} + +#[test] +fn merge_upstream() { + run_test("merge_upstream", |gh| async move { + let repo = gh.repository("ehuss/rust").await.unwrap(); + repo.merge_upstream(&gh, "docs-update").await.unwrap(); + }); +} + +#[test] +fn user() { + run_test("user", |gh| async move { + let user = triagebot::github::User::current(&gh).await.unwrap(); + assert_eq!(user.login, "ehuss"); + assert_eq!(user.id, Some(43198)); + }); +} + +#[test] +fn get_issues_no_search() { + run_test("get_issues_no_search", |gh| async move { + // get_issues where it doesn't use the search API + let repo = gh.repository("rust-lang/rust").await.unwrap(); + let issues = repo + .get_issues( + &gh, + &triagebot::github::Query { + filters: Vec::new(), + include_labels: vec!["A-coherence"], + exclude_labels: Vec::new(), + }, + ) + .await + .unwrap(); + assert_eq!(issues.len(), 3); + assert_eq!(issues[0].number, 99554); + assert_eq!(issues[1].number, 105782); + assert_eq!(issues[2].number, 105787); + }); +} + +#[test] +fn issue_properties() { + run_test("issue_properties", |gh| async move { + let repo = gh.repository("rust-lang/rust").await.unwrap(); + let issues = repo + .get_issues( + &gh, + &triagebot::github::Query { + filters: Vec::new(), + include_labels: vec!["A-coherence"], + exclude_labels: Vec::new(), + }, + ) + .await + .unwrap(); + assert_eq!(issues.len(), 3); + let issue = &issues[1]; + assert_eq!(issue.number, 105782); + assert!(issue + .body + .starts_with("which is unsound during coherence, as coherence requires completeness")); + assert_eq!(issue.created_at.to_string(), "2022-12-16 15:11:15 UTC"); + assert_eq!(issue.updated_at.to_string(), "2022-12-16 16:17:41 UTC"); + assert_eq!(issue.merge_commit_sha, None); + assert_eq!( + issue.title, + "specialization: default items completely drop candidates instead of ambiguity" + ); + assert_eq!( + issue.html_url, + "https://github.com/rust-lang/rust/issues/105782" + ); + assert_eq!(issue.user.login, "lcnr"); + assert_eq!(issue.user.id, Some(29864074)); + let labels: Vec<_> = issue.labels.iter().map(|s| s.name.as_str()).collect(); + assert_eq!( + labels, + &[ + "A-traits", + "I-unsound", + "A-specialization", + "C-bug", + "requires-nightly", + "F-specialization", + "A-coherence" + ] + ); + assert_eq!(issue.assignees, &[]); + assert!(issue.pull_request.is_none()); + assert_eq!(issue.merged, false); + assert_eq!(issue.draft, false); + assert!(issue.base.is_none()); + assert!(issue.head.is_none()); + assert_eq!(issue.state, triagebot::github::IssueState::Open); + + let repo = issue.repository(); + assert_eq!(repo.organization, "rust-lang"); + assert_eq!(repo.repository, "rust"); + + assert_eq!(issue.global_id(), "rust-lang/rust#105782"); + assert!(!issue.is_pr()); + assert!(issue.is_open()); + }); +} + +#[test] +fn get_issues_with_search() { + // Tests `get_issues()` where it needs to use the search API. + run_test("get_issues_with_search", |gh| async move { + // get_issues where it doesn't use the search API + let repo = gh.repository("rust-lang/rust").await.unwrap(); + let issues = repo + .get_issues( + &gh, + &triagebot::github::Query { + filters: vec![("state", "closed"), ("is", "pull-request")], + include_labels: vec!["beta-nominated", "beta-accepted"], + exclude_labels: vec![], + }, + ) + .await + .unwrap(); + assert_eq!(issues.len(), 3); + assert_eq!(issues[0].number, 107239); + assert_eq!(issues[1].number, 107357); + assert_eq!(issues[2].number, 107360); + }); +} diff --git a/tests/github_client/new_pr/00-GET-repos_ehuss_rust.json b/tests/github_client/new_pr/00-GET-repos_ehuss_rust.json new file mode 100644 index 00000000..60d9c4ff --- /dev/null +++ b/tests/github_client/new_pr/00-GET-repos_ehuss_rust.json @@ -0,0 +1,365 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/ehuss/rust", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/rust/branches{/branch}", + "clone_url": "https://github.com/ehuss/rust.git", + "collaborators_url": "https://api.github.com/repos/ehuss/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/rust/contributors", + "created_at": "2018-01-14T20:35:48Z", + "default_branch": "master", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/rust/deployments", + "description": "A safe, concurrent, practical language.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/rust/downloads", + "events_url": "https://api.github.com/repos/ehuss/rust/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/ehuss/rust/forks", + "full_name": "ehuss/rust", + "git_commits_url": "https://api.github.com/repos/ehuss/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/rust/git/tags{/sha}", + "git_url": "git://github.com/ehuss/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": false, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/ehuss/rust/hooks", + "html_url": "https://github.com/ehuss/rust", + "id": 117464625, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/ehuss/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/rust/merges", + "milestones_url": "https://api.github.com/repos/ehuss/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "network_count": 10326, + "node_id": "MDEwOlJlcG9zaXRvcnkxMTc0NjQ2MjU=", + "notifications_url": "https://api.github.com/repos/ehuss/rust/notifications{?since,all,participating}", + "open_issues": 0, + "open_issues_count": 0, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "parent": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10326, + "forks_count": 10326, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9513, + "open_issues_count": 9513, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T18:16:26Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066392, + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77402, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T19:09:47Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "visibility": "public", + "watchers": 77402, + "watchers_count": 77402, + "web_commit_signoff_required": false + }, + "permissions": { + "admin": true, + "maintain": true, + "pull": true, + "push": true, + "triage": true + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/rust/pulls{/number}", + "pushed_at": "2023-02-05T19:16:53Z", + "releases_url": "https://api.github.com/repos/ehuss/rust/releases{/id}", + "security_and_analysis": { + "secret_scanning": { + "status": "disabled" + }, + "secret_scanning_push_protection": { + "status": "disabled" + } + }, + "size": 1054343, + "source": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10326, + "forks_count": 10326, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9513, + "open_issues_count": 9513, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T18:16:26Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066392, + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77402, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T19:09:47Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "visibility": "public", + "watchers": 77402, + "watchers_count": 77402, + "web_commit_signoff_required": false + }, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/rust.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/rust/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/rust/statuses/{sha}", + "subscribers_count": 0, + "subscribers_url": "https://api.github.com/repos/ehuss/rust/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/rust/subscription", + "svn_url": "https://github.com/ehuss/rust", + "tags_url": "https://api.github.com/repos/ehuss/rust/tags", + "teams_url": "https://api.github.com/repos/ehuss/rust/teams", + "temp_clone_token": "", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/rust/git/trees{/sha}", + "updated_at": "2021-11-03T23:44:04Z", + "url": "https://api.github.com/repos/ehuss/rust", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + } +} diff --git a/tests/github_client/new_pr/01-POST-repos_ehuss_rust_pulls.json b/tests/github_client/new_pr/01-POST-repos_ehuss_rust_pulls.json new file mode 100644 index 00000000..42d7bed7 --- /dev/null +++ b/tests/github_client/new_pr/01-POST-repos_ehuss_rust_pulls.json @@ -0,0 +1,362 @@ +{ + "kind": "Request", + "method": "POST", + "path": "/repos/ehuss/rust/pulls", + "query": null, + "request_body": "{\"base\":\"master\",\"body\":\"example body text\",\"head\":\"ehuss:docs-update\",\"title\":\"example title\"}", + "response_code": 201, + "response_body": { + "_links": { + "comments": { + "href": "https://api.github.com/repos/ehuss/rust/issues/7/comments" + }, + "commits": { + "href": "https://api.github.com/repos/ehuss/rust/pulls/7/commits" + }, + "html": { + "href": "https://github.com/ehuss/rust/pull/7" + }, + "issue": { + "href": "https://api.github.com/repos/ehuss/rust/issues/7" + }, + "review_comment": { + "href": "https://api.github.com/repos/ehuss/rust/pulls/comments{/number}" + }, + "review_comments": { + "href": "https://api.github.com/repos/ehuss/rust/pulls/7/comments" + }, + "self": { + "href": "https://api.github.com/repos/ehuss/rust/pulls/7" + }, + "statuses": { + "href": "https://api.github.com/repos/ehuss/rust/statuses/88a426017fa4635ba42203c3b1d1c19f6a028184" + } + }, + "active_lock_reason": null, + "additions": 1, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "auto_merge": null, + "base": { + "label": "ehuss:master", + "ref": "master", + "repo": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/rust/branches{/branch}", + "clone_url": "https://github.com/ehuss/rust.git", + "collaborators_url": "https://api.github.com/repos/ehuss/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/rust/contributors", + "created_at": "2018-01-14T20:35:48Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/ehuss/rust/deployments", + "description": "A safe, concurrent, practical language.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/rust/downloads", + "events_url": "https://api.github.com/repos/ehuss/rust/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/ehuss/rust/forks", + "full_name": "ehuss/rust", + "git_commits_url": "https://api.github.com/repos/ehuss/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/rust/git/tags{/sha}", + "git_url": "git://github.com/ehuss/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": false, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/ehuss/rust/hooks", + "html_url": "https://github.com/ehuss/rust", + "id": 117464625, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/ehuss/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merges_url": "https://api.github.com/repos/ehuss/rust/merges", + "milestones_url": "https://api.github.com/repos/ehuss/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "node_id": "MDEwOlJlcG9zaXRvcnkxMTc0NjQ2MjU=", + "notifications_url": "https://api.github.com/repos/ehuss/rust/notifications{?since,all,participating}", + "open_issues": 1, + "open_issues_count": 1, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/rust/pulls{/number}", + "pushed_at": "2023-02-05T19:16:53Z", + "releases_url": "https://api.github.com/repos/ehuss/rust/releases{/id}", + "size": 1054343, + "ssh_url": "git@github.com:ehuss/rust.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/rust/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/rust/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/rust/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/rust/subscription", + "svn_url": "https://github.com/ehuss/rust", + "tags_url": "https://api.github.com/repos/ehuss/rust/tags", + "teams_url": "https://api.github.com/repos/ehuss/rust/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/rust/git/trees{/sha}", + "updated_at": "2021-11-03T23:44:04Z", + "url": "https://api.github.com/repos/ehuss/rust", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "319b88c463fe6f51bb6badbbd3bb97252a60f3a5", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "body": "example body text", + "changed_files": 1, + "closed_at": null, + "comments": 0, + "comments_url": "https://api.github.com/repos/ehuss/rust/issues/7/comments", + "commits": 1, + "commits_url": "https://api.github.com/repos/ehuss/rust/pulls/7/commits", + "created_at": "2023-02-05T19:20:58Z", + "deletions": 1, + "diff_url": "https://github.com/ehuss/rust/pull/7.diff", + "draft": false, + "head": { + "label": "ehuss:docs-update", + "ref": "docs-update", + "repo": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/rust/branches{/branch}", + "clone_url": "https://github.com/ehuss/rust.git", + "collaborators_url": "https://api.github.com/repos/ehuss/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/rust/contributors", + "created_at": "2018-01-14T20:35:48Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/ehuss/rust/deployments", + "description": "A safe, concurrent, practical language.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/rust/downloads", + "events_url": "https://api.github.com/repos/ehuss/rust/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/ehuss/rust/forks", + "full_name": "ehuss/rust", + "git_commits_url": "https://api.github.com/repos/ehuss/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/rust/git/tags{/sha}", + "git_url": "git://github.com/ehuss/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": false, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/ehuss/rust/hooks", + "html_url": "https://github.com/ehuss/rust", + "id": 117464625, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/ehuss/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merges_url": "https://api.github.com/repos/ehuss/rust/merges", + "milestones_url": "https://api.github.com/repos/ehuss/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "node_id": "MDEwOlJlcG9zaXRvcnkxMTc0NjQ2MjU=", + "notifications_url": "https://api.github.com/repos/ehuss/rust/notifications{?since,all,participating}", + "open_issues": 1, + "open_issues_count": 1, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/rust/pulls{/number}", + "pushed_at": "2023-02-05T19:16:53Z", + "releases_url": "https://api.github.com/repos/ehuss/rust/releases{/id}", + "size": 1054343, + "ssh_url": "git@github.com:ehuss/rust.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/rust/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/rust/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/rust/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/rust/subscription", + "svn_url": "https://github.com/ehuss/rust", + "tags_url": "https://api.github.com/repos/ehuss/rust/tags", + "teams_url": "https://api.github.com/repos/ehuss/rust/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/rust/git/trees{/sha}", + "updated_at": "2021-11-03T23:44:04Z", + "url": "https://api.github.com/repos/ehuss/rust", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "88a426017fa4635ba42203c3b1d1c19f6a028184", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "html_url": "https://github.com/ehuss/rust/pull/7", + "id": 1229569245, + "issue_url": "https://api.github.com/repos/ehuss/rust/issues/7", + "labels": [], + "locked": false, + "maintainer_can_modify": false, + "merge_commit_sha": null, + "mergeable": null, + "mergeable_state": "unknown", + "merged": false, + "merged_at": null, + "merged_by": null, + "milestone": null, + "node_id": "PR_kwDOBwBeMc5JSbzd", + "number": 7, + "patch_url": "https://github.com/ehuss/rust/pull/7.patch", + "rebaseable": null, + "requested_reviewers": [], + "requested_teams": [], + "review_comment_url": "https://api.github.com/repos/ehuss/rust/pulls/comments{/number}", + "review_comments": 0, + "review_comments_url": "https://api.github.com/repos/ehuss/rust/pulls/7/comments", + "state": "open", + "statuses_url": "https://api.github.com/repos/ehuss/rust/statuses/88a426017fa4635ba42203c3b1d1c19f6a028184", + "title": "example title", + "updated_at": "2023-02-05T19:20:58Z", + "url": "https://api.github.com/repos/ehuss/rust/pulls/7", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} diff --git a/tests/github_client/raw_file/00-GET-ehuss_triagebot-test_raw-file_docs_example_txt.json b/tests/github_client/raw_file/00-GET-ehuss_triagebot-test_raw-file_docs_example_txt.json new file mode 100644 index 00000000..87097e6d --- /dev/null +++ b/tests/github_client/raw_file/00-GET-ehuss_triagebot-test_raw-file_docs_example_txt.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/ehuss/triagebot-test/raw-file/docs/example.txt", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" +} diff --git a/tests/github_client/repository/00-GET-repos_rust-lang_rust.json b/tests/github_client/repository/00-GET-repos_rust-lang_rust.json new file mode 100644 index 00000000..c1bedcb0 --- /dev/null +++ b/tests/github_client/repository/00-GET-repos_rust-lang_rust.json @@ -0,0 +1,148 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10257, + "forks_count": 10257, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "network_count": 10257, + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9527, + "open_issues_count": 9527, + "organization": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "permissions": { + "admin": false, + "maintain": false, + "pull": true, + "push": true, + "triage": true + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-01-23T22:28:29Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1057370, + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 76867, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_count": 1481, + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-01-23T22:36:05Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "visibility": "public", + "watchers": 76867, + "watchers_count": 76867, + "web_commit_signoff_required": false + } +} diff --git a/tests/github_client/rust_commit/00-GET-repos_rust-lang_rust_commits_7632db0e87d8adccc9a83a47795c9411b1455855.json b/tests/github_client/rust_commit/00-GET-repos_rust-lang_rust_commits_7632db0e87d8adccc9a83a47795c9411b1455855.json new file mode 100644 index 00000000..48b3dffb --- /dev/null +++ b/tests/github_client/rust_commit/00-GET-repos_rust-lang_rust_commits_7632db0e87d8adccc9a83a47795c9411b1455855.json @@ -0,0 +1,123 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust/commits/7632db0e87d8adccc9a83a47795c9411b1455855", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "author": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "comments_url": "https://api.github.com/repos/rust-lang/rust/commits/7632db0e87d8adccc9a83a47795c9411b1455855/comments", + "commit": { + "author": { + "date": "2022-12-08T07:46:42Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "comment_count": 0, + "committer": { + "date": "2022-12-08T07:46:42Z", + "email": "bors@rust-lang.org", + "name": "bors" + }, + "message": "Auto merge of #105415 - nikic:update-llvm-10, r=cuviper\n\nUpdate LLVM submodule\n\nThis is a rebase to LLVM 15.0.6.\n\nFixes #103380.\nFixes #104099.", + "tree": { + "sha": "48b86a3f0b0ab76a8205a5b56444c7e511340f8a", + "url": "https://api.github.com/repos/rust-lang/rust/git/trees/48b86a3f0b0ab76a8205a5b56444c7e511340f8a" + }, + "url": "https://api.github.com/repos/rust-lang/rust/git/commits/7632db0e87d8adccc9a83a47795c9411b1455855", + "verification": { + "payload": null, + "reason": "unsigned", + "signature": null, + "verified": false + } + }, + "committer": { + "avatar_url": "https://avatars.githubusercontent.com/u/3372342?v=4", + "events_url": "https://api.github.com/users/bors/events{/privacy}", + "followers_url": "https://api.github.com/users/bors/followers", + "following_url": "https://api.github.com/users/bors/following{/other_user}", + "gists_url": "https://api.github.com/users/bors/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/bors", + "id": 3372342, + "login": "bors", + "node_id": "MDQ6VXNlcjMzNzIzNDI=", + "organizations_url": "https://api.github.com/users/bors/orgs", + "received_events_url": "https://api.github.com/users/bors/received_events", + "repos_url": "https://api.github.com/users/bors/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/bors/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bors/subscriptions", + "type": "User", + "url": "https://api.github.com/users/bors" + }, + "files": [ + { + "additions": 1, + "blob_url": "https://github.com/rust-lang/rust/blob/7632db0e87d8adccc9a83a47795c9411b1455855/.gitmodules", + "changes": 2, + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/.gitmodules?ref=7632db0e87d8adccc9a83a47795c9411b1455855", + "deletions": 1, + "filename": ".gitmodules", + "patch": "@@ -28,7 +28,7 @@\n [submodule \"src/llvm-project\"]\n \tpath = src/llvm-project\n \turl = https://github.com/rust-lang/llvm-project.git\n-\tbranch = rustc/15.0-2022-08-09\n+\tbranch = rustc/15.0-2022-12-07\n [submodule \"src/doc/embedded-book\"]\n \tpath = src/doc/embedded-book\n \turl = https://github.com/rust-embedded/book.git", + "raw_url": "https://github.com/rust-lang/rust/raw/7632db0e87d8adccc9a83a47795c9411b1455855/.gitmodules", + "sha": "4011a6fa6b95b3e0104a4f99ab5c912790d7a333", + "status": "modified" + }, + { + "additions": 1, + "blob_url": null, + "changes": 2, + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/src%2Fllvm-project?ref=7632db0e87d8adccc9a83a47795c9411b1455855", + "deletions": 1, + "filename": "src/llvm-project", + "patch": "@@ -1 +1 @@\n-Subproject commit a1232c451fc27173f8718e05d174b2503ca0b607\n+Subproject commit 3dfd4d93fa013e1c0578d3ceac5c8f4ebba4b6ec", + "raw_url": null, + "sha": "3dfd4d93fa013e1c0578d3ceac5c8f4ebba4b6ec", + "status": "modified" + } + ], + "html_url": "https://github.com/rust-lang/rust/commit/7632db0e87d8adccc9a83a47795c9411b1455855", + "node_id": "C_kwDOAAsO6NoAKDc2MzJkYjBlODdkOGFkY2NjOWE4M2E0Nzc5NWM5NDExYjE0NTU4NTU", + "parents": [ + { + "html_url": "https://github.com/rust-lang/rust/commit/f5418b09e84883c4de2e652a147ab9faff4eee29", + "sha": "f5418b09e84883c4de2e652a147ab9faff4eee29", + "url": "https://api.github.com/repos/rust-lang/rust/commits/f5418b09e84883c4de2e652a147ab9faff4eee29" + }, + { + "html_url": "https://github.com/rust-lang/rust/commit/530a687a4bb0bd0e8ab7b3f7d80f2c773be120ef", + "sha": "530a687a4bb0bd0e8ab7b3f7d80f2c773be120ef", + "url": "https://api.github.com/repos/rust-lang/rust/commits/530a687a4bb0bd0e8ab7b3f7d80f2c773be120ef" + } + ], + "sha": "7632db0e87d8adccc9a83a47795c9411b1455855", + "stats": { + "additions": 2, + "deletions": 2, + "total": 4 + }, + "url": "https://api.github.com/repos/rust-lang/rust/commits/7632db0e87d8adccc9a83a47795c9411b1455855" + } +} diff --git a/tests/github_client/submodule/00-GET-repos_rust-lang_rust.json b/tests/github_client/submodule/00-GET-repos_rust-lang_rust.json new file mode 100644 index 00000000..3589a6e8 --- /dev/null +++ b/tests/github_client/submodule/00-GET-repos_rust-lang_rust.json @@ -0,0 +1,160 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": false, + "allow_squash_merge": false, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "delete_branch_on_merge": true, + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10326, + "forks_count": 10326, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "network_count": 10326, + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9513, + "open_issues_count": 9513, + "organization": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "permissions": { + "admin": false, + "maintain": false, + "pull": true, + "push": true, + "triage": true + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T18:16:26Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066392, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77402, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_count": 1487, + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "temp_clone_token": "", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T19:09:47Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 77402, + "watchers_count": 77402, + "web_commit_signoff_required": false + } +} diff --git a/tests/github_client/submodule/01-GET-repos_rust-lang_rust_contents_src_doc_reference.json b/tests/github_client/submodule/01-GET-repos_rust-lang_rust_contents_src_doc_reference.json new file mode 100644 index 00000000..53d5a0ab --- /dev/null +++ b/tests/github_client/submodule/01-GET-repos_rust-lang_rust_contents_src_doc_reference.json @@ -0,0 +1,25 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/rust/contents/src/doc/reference", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "_links": { + "git": "https://api.github.com/repos/rust-lang/reference/git/trees/22882fb3f7b4d69fdc0d1731e8b9cfcb6910537d", + "html": "https://github.com/rust-lang/reference/tree/22882fb3f7b4d69fdc0d1731e8b9cfcb6910537d", + "self": "https://api.github.com/repos/rust-lang/rust/contents/src/doc/reference?ref=master" + }, + "download_url": null, + "git_url": "https://api.github.com/repos/rust-lang/reference/git/trees/22882fb3f7b4d69fdc0d1731e8b9cfcb6910537d", + "html_url": "https://github.com/rust-lang/reference/tree/22882fb3f7b4d69fdc0d1731e8b9cfcb6910537d", + "name": "reference", + "path": "src/doc/reference", + "sha": "22882fb3f7b4d69fdc0d1731e8b9cfcb6910537d", + "size": 0, + "submodule_git_url": "https://github.com/rust-lang/reference.git", + "type": "submodule", + "url": "https://api.github.com/repos/rust-lang/rust/contents/src/doc/reference?ref=master" + } +} diff --git a/tests/github_client/submodule/02-GET-repos_rust-lang_reference.json b/tests/github_client/submodule/02-GET-repos_rust-lang_reference.json new file mode 100644 index 00000000..8ec96de6 --- /dev/null +++ b/tests/github_client/submodule/02-GET-repos_rust-lang_reference.json @@ -0,0 +1,160 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/rust-lang/reference", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/rust-lang/reference/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/reference/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/reference/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/reference/branches{/branch}", + "clone_url": "https://github.com/rust-lang/reference.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/reference/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/reference/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/reference/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/reference/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/reference/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/reference/contributors", + "created_at": "2017-03-01T16:21:06Z", + "default_branch": "master", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/rust-lang/reference/deployments", + "description": "The Rust Reference", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/reference/downloads", + "events_url": "https://api.github.com/repos/rust-lang/reference/events", + "fork": false, + "forks": 361, + "forks_count": 361, + "forks_url": "https://api.github.com/repos/rust-lang/reference/forks", + "full_name": "rust-lang/reference", + "git_commits_url": "https://api.github.com/repos/rust-lang/reference/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/reference/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/reference/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/reference.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://doc.rust-lang.org/nightly/reference/", + "hooks_url": "https://api.github.com/repos/rust-lang/reference/hooks", + "html_url": "https://github.com/rust-lang/reference", + "id": 83575374, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/reference/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/reference/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/reference/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/reference/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/reference/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/reference/languages", + "license": { + "key": "apache-2.0", + "name": "Apache License 2.0", + "node_id": "MDc6TGljZW5zZTI=", + "spdx_id": "Apache-2.0", + "url": "https://api.github.com/licenses/apache-2.0" + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/rust-lang/reference/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/reference/milestones{/number}", + "mirror_url": null, + "name": "reference", + "network_count": 361, + "node_id": "MDEwOlJlcG9zaXRvcnk4MzU3NTM3NA==", + "notifications_url": "https://api.github.com/repos/rust-lang/reference/notifications{?since,all,participating}", + "open_issues": 257, + "open_issues_count": 257, + "organization": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "permissions": { + "admin": false, + "maintain": false, + "pull": true, + "push": true, + "triage": true + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/reference/pulls{/number}", + "pushed_at": "2023-02-04T22:41:51Z", + "releases_url": "https://api.github.com/repos/rust-lang/reference/releases{/id}", + "size": 4086, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:rust-lang/reference.git", + "stargazers_count": 878, + "stargazers_url": "https://api.github.com/repos/rust-lang/reference/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/reference/statuses/{sha}", + "subscribers_count": 37, + "subscribers_url": "https://api.github.com/repos/rust-lang/reference/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/reference/subscription", + "svn_url": "https://github.com/rust-lang/reference", + "tags_url": "https://api.github.com/repos/rust-lang/reference/tags", + "teams_url": "https://api.github.com/repos/rust-lang/reference/teams", + "temp_clone_token": "", + "topics": [ + "documentation", + "reference", + "rust", + "rust-lang" + ], + "trees_url": "https://api.github.com/repos/rust-lang/reference/git/trees{/sha}", + "updated_at": "2023-02-05T11:50:19Z", + "url": "https://api.github.com/repos/rust-lang/reference", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 878, + "watchers_count": 878, + "web_commit_signoff_required": false + } +} diff --git a/tests/github_client/update_reference/00-GET-repos_ehuss_rust.json b/tests/github_client/update_reference/00-GET-repos_ehuss_rust.json new file mode 100644 index 00000000..1d6b5bcd --- /dev/null +++ b/tests/github_client/update_reference/00-GET-repos_ehuss_rust.json @@ -0,0 +1,365 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/ehuss/rust", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/rust/branches{/branch}", + "clone_url": "https://github.com/ehuss/rust.git", + "collaborators_url": "https://api.github.com/repos/ehuss/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/rust/contributors", + "created_at": "2018-01-14T20:35:48Z", + "default_branch": "master", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/rust/deployments", + "description": "A safe, concurrent, practical language.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/rust/downloads", + "events_url": "https://api.github.com/repos/ehuss/rust/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/ehuss/rust/forks", + "full_name": "ehuss/rust", + "git_commits_url": "https://api.github.com/repos/ehuss/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/rust/git/tags{/sha}", + "git_url": "git://github.com/ehuss/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": false, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/ehuss/rust/hooks", + "html_url": "https://github.com/ehuss/rust", + "id": 117464625, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/ehuss/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/rust/merges", + "milestones_url": "https://api.github.com/repos/ehuss/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "network_count": 10326, + "node_id": "MDEwOlJlcG9zaXRvcnkxMTc0NjQ2MjU=", + "notifications_url": "https://api.github.com/repos/ehuss/rust/notifications{?since,all,participating}", + "open_issues": 0, + "open_issues_count": 0, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "parent": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10326, + "forks_count": 10326, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9513, + "open_issues_count": 9513, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T18:16:26Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066392, + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77402, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T19:09:47Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "visibility": "public", + "watchers": 77402, + "watchers_count": 77402, + "web_commit_signoff_required": false + }, + "permissions": { + "admin": true, + "maintain": true, + "pull": true, + "push": true, + "triage": true + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/rust/pulls{/number}", + "pushed_at": "2023-02-05T19:01:28Z", + "releases_url": "https://api.github.com/repos/ehuss/rust/releases{/id}", + "security_and_analysis": { + "secret_scanning": { + "status": "disabled" + }, + "secret_scanning_push_protection": { + "status": "disabled" + } + }, + "size": 1054343, + "source": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10326, + "forks_count": 10326, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9513, + "open_issues_count": 9513, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T18:16:26Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066392, + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77402, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T19:09:47Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "visibility": "public", + "watchers": 77402, + "watchers_count": 77402, + "web_commit_signoff_required": false + }, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/rust.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/rust/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/rust/statuses/{sha}", + "subscribers_count": 0, + "subscribers_url": "https://api.github.com/repos/ehuss/rust/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/rust/subscription", + "svn_url": "https://github.com/ehuss/rust", + "tags_url": "https://api.github.com/repos/ehuss/rust/tags", + "teams_url": "https://api.github.com/repos/ehuss/rust/teams", + "temp_clone_token": "", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/rust/git/trees{/sha}", + "updated_at": "2021-11-03T23:44:04Z", + "url": "https://api.github.com/repos/ehuss/rust", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + } +} diff --git a/tests/github_client/update_reference/01-PATCH-repos_ehuss_rust_git_refs_heads_docs-update.json b/tests/github_client/update_reference/01-PATCH-repos_ehuss_rust_git_refs_heads_docs-update.json new file mode 100644 index 00000000..112e4f7b --- /dev/null +++ b/tests/github_client/update_reference/01-PATCH-repos_ehuss_rust_git_refs_heads_docs-update.json @@ -0,0 +1,18 @@ +{ + "kind": "Request", + "method": "PATCH", + "path": "/repos/ehuss/rust/git/refs/heads/docs-update", + "query": null, + "request_body": "{\"force\":true,\"sha\":\"88a426017fa4635ba42203c3b1d1c19f6a028184\"}", + "response_code": 200, + "response_body": { + "node_id": "MDM6UmVmMTE3NDY0NjI1OnJlZnMvaGVhZHMvZG9jcy11cGRhdGU=", + "object": { + "sha": "88a426017fa4635ba42203c3b1d1c19f6a028184", + "type": "commit", + "url": "https://api.github.com/repos/ehuss/rust/git/commits/88a426017fa4635ba42203c3b1d1c19f6a028184" + }, + "ref": "refs/heads/docs-update", + "url": "https://api.github.com/repos/ehuss/rust/git/refs/heads/docs-update" + } +} diff --git a/tests/github_client/update_tree/00-GET-repos_ehuss_rust.json b/tests/github_client/update_tree/00-GET-repos_ehuss_rust.json new file mode 100644 index 00000000..2e719ca7 --- /dev/null +++ b/tests/github_client/update_tree/00-GET-repos_ehuss_rust.json @@ -0,0 +1,365 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/ehuss/rust", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/rust/branches{/branch}", + "clone_url": "https://github.com/ehuss/rust.git", + "collaborators_url": "https://api.github.com/repos/ehuss/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/rust/contributors", + "created_at": "2018-01-14T20:35:48Z", + "default_branch": "master", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/rust/deployments", + "description": "A safe, concurrent, practical language.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/rust/downloads", + "events_url": "https://api.github.com/repos/ehuss/rust/events", + "fork": true, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/ehuss/rust/forks", + "full_name": "ehuss/rust", + "git_commits_url": "https://api.github.com/repos/ehuss/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/rust/git/tags{/sha}", + "git_url": "git://github.com/ehuss/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": false, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/ehuss/rust/hooks", + "html_url": "https://github.com/ehuss/rust", + "id": 117464625, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/ehuss/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/rust/merges", + "milestones_url": "https://api.github.com/repos/ehuss/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "network_count": 10326, + "node_id": "MDEwOlJlcG9zaXRvcnkxMTc0NjQ2MjU=", + "notifications_url": "https://api.github.com/repos/ehuss/rust/notifications{?since,all,participating}", + "open_issues": 0, + "open_issues_count": 0, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "parent": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10326, + "forks_count": 10326, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9513, + "open_issues_count": 9513, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T18:16:26Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066392, + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77401, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T17:54:34Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "visibility": "public", + "watchers": 77401, + "watchers_count": 77401, + "web_commit_signoff_required": false + }, + "permissions": { + "admin": true, + "maintain": true, + "pull": true, + "push": true, + "triage": true + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/rust/pulls{/number}", + "pushed_at": "2023-02-05T19:01:28Z", + "releases_url": "https://api.github.com/repos/ehuss/rust/releases{/id}", + "security_and_analysis": { + "secret_scanning": { + "status": "disabled" + }, + "secret_scanning_push_protection": { + "status": "disabled" + } + }, + "size": 1054343, + "source": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/rust-lang/rust/assignees{/user}", + "blobs_url": "https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/rust-lang/rust/branches{/branch}", + "clone_url": "https://github.com/rust-lang/rust.git", + "collaborators_url": "https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/rust-lang/rust/comments{/number}", + "commits_url": "https://api.github.com/repos/rust-lang/rust/commits{/sha}", + "compare_url": "https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/rust-lang/rust/contents/{+path}", + "contributors_url": "https://api.github.com/repos/rust-lang/rust/contributors", + "created_at": "2010-06-16T20:39:03Z", + "default_branch": "master", + "deployments_url": "https://api.github.com/repos/rust-lang/rust/deployments", + "description": "Empowering everyone to build reliable and efficient software.", + "disabled": false, + "downloads_url": "https://api.github.com/repos/rust-lang/rust/downloads", + "events_url": "https://api.github.com/repos/rust-lang/rust/events", + "fork": false, + "forks": 10326, + "forks_count": 10326, + "forks_url": "https://api.github.com/repos/rust-lang/rust/forks", + "full_name": "rust-lang/rust", + "git_commits_url": "https://api.github.com/repos/rust-lang/rust/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/rust-lang/rust/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/rust-lang/rust/git/tags{/sha}", + "git_url": "git://github.com/rust-lang/rust.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": "https://www.rust-lang.org", + "hooks_url": "https://api.github.com/repos/rust-lang/rust/hooks", + "html_url": "https://github.com/rust-lang/rust", + "id": 724712, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/rust-lang/rust/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/rust-lang/rust/issues/events{/number}", + "issues_url": "https://api.github.com/repos/rust-lang/rust/issues{/number}", + "keys_url": "https://api.github.com/repos/rust-lang/rust/keys{/key_id}", + "labels_url": "https://api.github.com/repos/rust-lang/rust/labels{/name}", + "language": "Rust", + "languages_url": "https://api.github.com/repos/rust-lang/rust/languages", + "license": { + "key": "other", + "name": "Other", + "node_id": "MDc6TGljZW5zZTA=", + "spdx_id": "NOASSERTION", + "url": null + }, + "merges_url": "https://api.github.com/repos/rust-lang/rust/merges", + "milestones_url": "https://api.github.com/repos/rust-lang/rust/milestones{/number}", + "mirror_url": null, + "name": "rust", + "node_id": "MDEwOlJlcG9zaXRvcnk3MjQ3MTI=", + "notifications_url": "https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}", + "open_issues": 9513, + "open_issues_count": 9513, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/5430905?v=4", + "events_url": "https://api.github.com/users/rust-lang/events{/privacy}", + "followers_url": "https://api.github.com/users/rust-lang/followers", + "following_url": "https://api.github.com/users/rust-lang/following{/other_user}", + "gists_url": "https://api.github.com/users/rust-lang/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/rust-lang", + "id": 5430905, + "login": "rust-lang", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0MzA5MDU=", + "organizations_url": "https://api.github.com/users/rust-lang/orgs", + "received_events_url": "https://api.github.com/users/rust-lang/received_events", + "repos_url": "https://api.github.com/users/rust-lang/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/rust-lang/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/rust-lang/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/rust-lang" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/rust-lang/rust/pulls{/number}", + "pushed_at": "2023-02-05T18:16:26Z", + "releases_url": "https://api.github.com/repos/rust-lang/rust/releases{/id}", + "size": 1066392, + "ssh_url": "git@github.com:rust-lang/rust.git", + "stargazers_count": 77401, + "stargazers_url": "https://api.github.com/repos/rust-lang/rust/stargazers", + "statuses_url": "https://api.github.com/repos/rust-lang/rust/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/rust-lang/rust/subscribers", + "subscription_url": "https://api.github.com/repos/rust-lang/rust/subscription", + "svn_url": "https://github.com/rust-lang/rust", + "tags_url": "https://api.github.com/repos/rust-lang/rust/tags", + "teams_url": "https://api.github.com/repos/rust-lang/rust/teams", + "topics": [ + "compiler", + "hacktoberfest", + "language", + "rust" + ], + "trees_url": "https://api.github.com/repos/rust-lang/rust/git/trees{/sha}", + "updated_at": "2023-02-05T17:54:34Z", + "url": "https://api.github.com/repos/rust-lang/rust", + "visibility": "public", + "watchers": 77401, + "watchers_count": 77401, + "web_commit_signoff_required": false + }, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/rust.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/rust/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/rust/statuses/{sha}", + "subscribers_count": 0, + "subscribers_url": "https://api.github.com/repos/ehuss/rust/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/rust/subscription", + "svn_url": "https://github.com/ehuss/rust", + "tags_url": "https://api.github.com/repos/ehuss/rust/tags", + "teams_url": "https://api.github.com/repos/ehuss/rust/teams", + "temp_clone_token": "", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/rust/git/trees{/sha}", + "updated_at": "2021-11-03T23:44:04Z", + "url": "https://api.github.com/repos/ehuss/rust", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + } +} diff --git a/tests/github_client/update_tree/01-POST-repos_ehuss_rust_git_trees.json b/tests/github_client/update_tree/01-POST-repos_ehuss_rust_git_trees.json new file mode 100644 index 00000000..89849750 --- /dev/null +++ b/tests/github_client/update_tree/01-POST-repos_ehuss_rust_git_trees.json @@ -0,0 +1,240 @@ +{ + "kind": "Request", + "method": "POST", + "path": "/repos/ehuss/rust/git/trees", + "query": null, + "request_body": "{\"base_tree\":\"6ebac807802fa2458d2f47c2c12fb1e62944e764\",\"tree\":[{\"mode\":\"160000\",\"path\":\"src/doc/reference\",\"sha\":\"b9ccb0960e5e98154020d4c02a09cc3901bc2500\",\"type\":\"commit\"}]}", + "response_code": 201, + "response_body": { + "sha": "45aae523b087e418f2778d4557489de38fede6a3", + "tree": [ + { + "mode": "100644", + "path": ".editorconfig", + "sha": "ec6e107d547f0e6d7ff63e4866a641e3d2c4d1a5", + "size": 417, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/ec6e107d547f0e6d7ff63e4866a641e3d2c4d1a5" + }, + { + "mode": "100644", + "path": ".git-blame-ignore-revs", + "sha": "d20f19e60e86033722853348908ff38b73898ac4", + "size": 369, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/d20f19e60e86033722853348908ff38b73898ac4" + }, + { + "mode": "100644", + "path": ".gitattributes", + "sha": "51a670b5fbefdaf7904f1d304ea482b0543bc9a9", + "size": 464, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/51a670b5fbefdaf7904f1d304ea482b0543bc9a9" + }, + { + "mode": "040000", + "path": ".github", + "sha": "5664fb0635551f559db94dda7e7f5cd87d3dfc8e", + "type": "tree", + "url": "https://api.github.com/repos/ehuss/rust/git/trees/5664fb0635551f559db94dda7e7f5cd87d3dfc8e" + }, + { + "mode": "100644", + "path": ".gitignore", + "sha": "e5ca3e503130f63c8fb35475b0658dd4316a31b5", + "size": 1289, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/e5ca3e503130f63c8fb35475b0658dd4316a31b5" + }, + { + "mode": "100644", + "path": ".gitmodules", + "sha": "4011a6fa6b95b3e0104a4f99ab5c912790d7a333", + "size": 1365, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/4011a6fa6b95b3e0104a4f99ab5c912790d7a333" + }, + { + "mode": "100644", + "path": ".mailmap", + "sha": "8ed692989ccbf73baf3dbe06012380237c5b3a56", + "size": 29527, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/8ed692989ccbf73baf3dbe06012380237c5b3a56" + }, + { + "mode": "040000", + "path": ".reuse", + "sha": "60a2be0267d564a5c4f7e0c95949ebd1504587fa", + "type": "tree", + "url": "https://api.github.com/repos/ehuss/rust/git/trees/60a2be0267d564a5c4f7e0c95949ebd1504587fa" + }, + { + "mode": "100644", + "path": "CODE_OF_CONDUCT.md", + "sha": "e3708bc485399fd42b32c6a1c24491771afa1a04", + "size": 131, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/e3708bc485399fd42b32c6a1c24491771afa1a04" + }, + { + "mode": "100644", + "path": "CONTRIBUTING.md", + "sha": "d732075fb2d07fb84f1873ac7221f64f52a47947", + "size": 2448, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/d732075fb2d07fb84f1873ac7221f64f52a47947" + }, + { + "mode": "100644", + "path": "COPYRIGHT", + "sha": "05993830a0fb4ab5d30336f75be3e5001e1fc770", + "size": 21109, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/05993830a0fb4ab5d30336f75be3e5001e1fc770" + }, + { + "mode": "100644", + "path": "Cargo.lock", + "sha": "705210e44b24c5f67e39747bfacbae2ce1deceb6", + "size": 139425, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/705210e44b24c5f67e39747bfacbae2ce1deceb6" + }, + { + "mode": "100644", + "path": "Cargo.toml", + "sha": "15cbb2659c9b335ea3f1bb9b77af86f3b74bd8fc", + "size": 4562, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/15cbb2659c9b335ea3f1bb9b77af86f3b74bd8fc" + }, + { + "mode": "100644", + "path": "LICENSE-APACHE", + "sha": "1b5ec8b78e237b5c3b3d812a7c0a6589d0f7161d", + "size": 9723, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/1b5ec8b78e237b5c3b3d812a7c0a6589d0f7161d" + }, + { + "mode": "100644", + "path": "LICENSE-MIT", + "sha": "31aa79387f27e730e33d871925e152e35e428031", + "size": 1023, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/31aa79387f27e730e33d871925e152e35e428031" + }, + { + "mode": "040000", + "path": "LICENSES", + "sha": "5024f3351b8c6791ba50e5454a0fc1c33f220bf6", + "type": "tree", + "url": "https://api.github.com/repos/ehuss/rust/git/trees/5024f3351b8c6791ba50e5454a0fc1c33f220bf6" + }, + { + "mode": "100644", + "path": "README.md", + "sha": "0eb7c4b266a9f3a529e1b3c555ac2bf1dee974c1", + "size": 10251, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/0eb7c4b266a9f3a529e1b3c555ac2bf1dee974c1" + }, + { + "mode": "100644", + "path": "RELEASES.md", + "sha": "a63d4e8a043c606e4384eb5b7f6d6bc581802de9", + "size": 624629, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/a63d4e8a043c606e4384eb5b7f6d6bc581802de9" + }, + { + "mode": "040000", + "path": "compiler", + "sha": "620c4ab1d299192130aeb719e70bc1cab7ca0677", + "type": "tree", + "url": "https://api.github.com/repos/ehuss/rust/git/trees/620c4ab1d299192130aeb719e70bc1cab7ca0677" + }, + { + "mode": "100644", + "path": "config.toml.example", + "sha": "df4478bb0cb85ac75cfb31fbc78349d30fcfa96b", + "size": 34209, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/df4478bb0cb85ac75cfb31fbc78349d30fcfa96b" + }, + { + "mode": "100755", + "path": "configure", + "sha": "81e2001e4a583ef1f117a46593acd1705995ed85", + "size": 292, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/81e2001e4a583ef1f117a46593acd1705995ed85" + }, + { + "mode": "040000", + "path": "library", + "sha": "808258f2e74d534960aee1599688512f14eb279c", + "type": "tree", + "url": "https://api.github.com/repos/ehuss/rust/git/trees/808258f2e74d534960aee1599688512f14eb279c" + }, + { + "mode": "100644", + "path": "rustfmt.toml", + "sha": "828d492a3d19c892b53168bbe8f280641f6b28bd", + "size": 1304, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/828d492a3d19c892b53168bbe8f280641f6b28bd" + }, + { + "mode": "040000", + "path": "src", + "sha": "06a6ef9fe702a0a7616d3602f9d09ffbe5c4b775", + "type": "tree", + "url": "https://api.github.com/repos/ehuss/rust/git/trees/06a6ef9fe702a0a7616d3602f9d09ffbe5c4b775" + }, + { + "mode": "040000", + "path": "tests", + "sha": "77bbb489e5cdde6860d3bb4e705009908153cd5a", + "type": "tree", + "url": "https://api.github.com/repos/ehuss/rust/git/trees/77bbb489e5cdde6860d3bb4e705009908153cd5a" + }, + { + "mode": "100644", + "path": "triagebot.toml", + "sha": "62a99b704388fc857d527e61f96b5cf407c43a24", + "size": 18061, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/62a99b704388fc857d527e61f96b5cf407c43a24" + }, + { + "mode": "100755", + "path": "x", + "sha": "4309b82627c9c47917df4ef29c9ef8c4a3020544", + "size": 1161, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/4309b82627c9c47917df4ef29c9ef8c4a3020544" + }, + { + "mode": "100755", + "path": "x.ps1", + "sha": "f324a4676c8e99d5f338eaa0c11020db0f4b5e0b", + "size": 1442, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/f324a4676c8e99d5f338eaa0c11020db0f4b5e0b" + }, + { + "mode": "100755", + "path": "x.py", + "sha": "5dee953a31899ff46fe3f459de48d8249ce2a4b2", + "size": 948, + "type": "blob", + "url": "https://api.github.com/repos/ehuss/rust/git/blobs/5dee953a31899ff46fe3f459de48d8249ce2a4b2" + } + ], + "truncated": false, + "url": "https://api.github.com/repos/ehuss/rust/git/trees/45aae523b087e418f2778d4557489de38fede6a3" + } +} diff --git a/tests/github_client/user/00-GET-user.json b/tests/github_client/user/00-GET-user.json new file mode 100644 index 00000000..effe11b0 --- /dev/null +++ b/tests/github_client/user/00-GET-user.json @@ -0,0 +1,42 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/user", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "bio": null, + "blog": "", + "company": null, + "created_at": "2008-12-29T20:01:15Z", + "email": null, + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers": 125, + "followers_url": "https://api.github.com/users/ehuss/followers", + "following": 0, + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "hireable": null, + "html_url": "https://github.com/ehuss", + "id": 43198, + "location": null, + "login": "ehuss", + "name": "Eric Huss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "public_gists": 1, + "public_repos": 155, + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "twitter_username": null, + "type": "User", + "updated_at": "2022-11-25T21:26:50Z", + "url": "https://api.github.com/users/ehuss" + } +} diff --git a/tests/server_test/mentions.rs b/tests/server_test/mentions.rs new file mode 100644 index 00000000..18e55be7 --- /dev/null +++ b/tests/server_test/mentions.rs @@ -0,0 +1,191 @@ +use crate::server_test::close_opened_prs; +use super::run_test; +use crate::server_test::TestPrBuilder; +use triagebot::github::GitTreeEntry; +use triagebot::github::GithubClient; +use triagebot::github::Issue; + +async fn expected_comments(gh: &GithubClient, pr: &Issue, comments: &[&str]) { + let mut found = false; + // This repeats to make sure that no unexpected additional comments are posted. + for _ in 0..5 { + let current_comments = pr.get_comments(gh).await.unwrap(); + let n_current = current_comments.len(); + let n_expected = comments.len(); + if n_current < n_expected { + } else if n_current == n_expected { + found = true; + } else { + panic!( + "too many comments received (got {n_current} expected {n_expected}):\n\ + expected:\n\ + {comments:?}\n\ + \n\ + got:\n\ + {current_comments:#?}" + ); + } + tokio::time::sleep(std::time::Duration::new(5, 0)).await; + } + if !found { + panic!( + "did not find expected comments {comments:?} on PR {}", + pr.html_url + ); + } +} + +#[test] +fn default_mention() { + // A new PR that touches a file in the [mentions] config with the default + // message. + run_test("mentions/default_mention", |setup| async move { + setup + .config( + r#" + [mentions.'foo/example1'] + cc = ["@octocat"] + "#, + ) + .await; + close_opened_prs(&setup.gh, &setup.repo, "mentions-test").await; + let ctx = setup.launch_triagebot_live(); + let gh = ctx.gh.as_ref().unwrap(); + let repo = ctx.repo.as_ref().unwrap(); + let pr = TestPrBuilder::new("mentions-test", &repo.default_branch) + .file("foo/example1", false, "sample text") + .create(gh, repo) + .await; + expected_comments( + gh, + &pr, + &["Some changes occurred in foo/example1\n\ncc @octocat"], + ).await; + }); +} + +#[test] +fn custom_message() { + // A new PR that touches a file in the [mentions] config with a custom + // message. + run_test("mentions/custom_mention", |setup| async move { + setup + .config( + r#" + [mentions.'foo/example1'] + cc = ["@octocat"] + message = "a custom message" + "#, + ) + .await; + close_opened_prs(&setup.gh, &setup.repo, "mentions-test").await; + let ctx = setup.launch_triagebot_live(); + let gh = ctx.gh.as_ref().unwrap(); + let repo = ctx.repo.as_ref().unwrap(); + let pr = TestPrBuilder::new("mentions-test", &repo.default_branch) + .file("foo/example1", false, "sample text") + .create(gh, repo) + .await; + expected_comments(gh, &pr, &["a custom message\n\ncc @octocat"]).await; + }); +} + +// "response_body": "[mentions.'foo/example1']\n +// cc = [\"@grashgal\", \"@ehuss\"]\n\n +// [mentions.'foo/example2']\n +// cc = [\"@grashgal\", \"@ehuss\"]\nmessage = \"a custom message\"\n" + +#[test] +fn dont_mention_twice() { + // When pushing modifications to the same files, don't mention again. + // + // However if a push comes in for a different file, make sure it mentions again. + // + // This starts with a new PR adding example1/README.md. + // It then pushes an update to example1/README.md. + // And then a second update to add example2/README.md. + run_test("mentions/dont_mention_twice", |setup| async move { + setup + .config( + r#" + [mentions.'foo/example1'] + cc = ["@octocat"] + + [mentions.'foo/example2'] + cc = ["@octocat"] + "#, + ) + .await; + close_opened_prs(&setup.gh, &setup.repo, "mentions-test").await; + let ctx = setup.launch_triagebot_live(); + let gh = ctx.gh.as_ref().unwrap(); + let repo = ctx.repo.as_ref().unwrap(); + let pr = TestPrBuilder::new("mentions-test", &repo.default_branch) + .file("foo/example1", false, "sample text") + .create(gh, repo) + .await; + expected_comments( + gh, + &pr, + &["Some changes occurred in foo/example1\n\ncc @octocat"], + ).await; + // Updating the same file should not comment again. + let commits = pr.commits(gh).await.unwrap(); + let last_commit = commits.last().unwrap(); + let tree_entries = vec![GitTreeEntry { + path: "foo/example1".into(), + mode: "100644".into(), + object_type: "blob".into(), + sha: None, + content: Some("this file has been edited".into()), + }]; + let new_tree = repo + .update_tree(gh, &last_commit.commit.tree.sha, &tree_entries) + .await + .unwrap(); + let commit = repo + .create_commit(gh, "editing example1", &[&last_commit.sha], &new_tree.sha) + .await + .unwrap(); + repo.update_reference(gh, &format!("heads/mentions-test"), &commit.sha) + .await + .unwrap(); + expected_comments( + gh, + &pr, + &["Some changes occurred in foo/example1\n\ncc @octocat"], + ) + .await; + + // Updating a different file should mention again (even for the same user). + let commits = pr.commits(gh).await.unwrap(); + let last_commit = commits.last().unwrap(); + let tree_entries = vec![GitTreeEntry { + path: "foo/example2".into(), + mode: "100644".into(), + object_type: "blob".into(), + sha: None, + content: Some("adding a second file".into()), + }]; + let new_tree = repo + .update_tree(gh, &last_commit.commit.tree.sha, &tree_entries) + .await + .unwrap(); + let commit = repo + .create_commit(gh, "adding example2", &[&last_commit.sha], &new_tree.sha) + .await + .unwrap(); + repo.update_reference(gh, &format!("heads/mentions-test"), &commit.sha) + .await + .unwrap(); + expected_comments( + gh, + &pr, + &[ + "Some changes occurred in foo/example1\n\ncc @octocat", + "Some changes occurred in foo/example2\n\ncc @octocat", + ], + ) + .await; + }); +} diff --git a/tests/server_test/mentions/custom_mention/00-webhook-pr110_closed.json b/tests/server_test/mentions/custom_mention/00-webhook-pr110_closed.json new file mode 100644 index 00000000..a44784a5 --- /dev/null +++ b/tests/server_test/mentions/custom_mention/00-webhook-pr110_closed.json @@ -0,0 +1,492 @@ +{ + "kind": "Webhook", + "webhook_event": "pull_request", + "payload": { + "action": "closed", + "number": 110, + "pull_request": { + "_links": { + "comments": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/issues/110/comments" + }, + "commits": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/110/commits" + }, + "html": { + "href": "https://github.com/ehuss/triagebot-test/pull/110" + }, + "issue": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/issues/110" + }, + "review_comment": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/comments{/number}" + }, + "review_comments": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/110/comments" + }, + "self": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/110" + }, + "statuses": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/statuses/51f5007fddf25f6a92a0e35fafcf65de108050e5" + } + }, + "active_lock_reason": null, + "additions": 1, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "auto_merge": null, + "base": { + "label": "ehuss:main", + "ref": "main", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T02:40:09Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "5edf4816bca5327fa426c30bc6ca86d6475f13ad", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "body": "This is a test PR.", + "changed_files": 1, + "closed_at": "2023-03-08T02:40:13Z", + "comments": 1, + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/110/comments", + "commits": 1, + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/110/commits", + "created_at": "2023-03-08T02:39:38Z", + "deletions": 0, + "diff_url": "https://github.com/ehuss/triagebot-test/pull/110.diff", + "draft": false, + "head": { + "label": "ehuss:mentions-test", + "ref": "mentions-test", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T02:40:09Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "51f5007fddf25f6a92a0e35fafcf65de108050e5", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "html_url": "https://github.com/ehuss/triagebot-test/pull/110", + "id": 1267249548, + "issue_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/110", + "labels": [], + "locked": false, + "maintainer_can_modify": false, + "merge_commit_sha": "60dc009f85bebc85152ec8074f2d0cdcc80f2036", + "mergeable": null, + "mergeable_state": "unknown", + "merged": false, + "merged_at": null, + "merged_by": null, + "milestone": null, + "node_id": "PR_kwDOHkK3Xc5LiLGM", + "number": 110, + "patch_url": "https://github.com/ehuss/triagebot-test/pull/110.patch", + "rebaseable": null, + "requested_reviewers": [], + "requested_teams": [], + "review_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/comments{/number}", + "review_comments": 0, + "review_comments_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/110/comments", + "state": "closed", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/51f5007fddf25f6a92a0e35fafcf65de108050e5", + "title": "Test PR", + "updated_at": "2023-03-08T02:40:13Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/110", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T02:40:09Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/mentions/custom_mention/01-GET-ehuss_triagebot-test_main_triagebot_toml.json b/tests/server_test/mentions/custom_mention/01-GET-ehuss_triagebot-test_main_triagebot_toml.json new file mode 100644 index 00000000..7524376b --- /dev/null +++ b/tests/server_test/mentions/custom_mention/01-GET-ehuss_triagebot-test_main_triagebot_toml.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/ehuss/triagebot-test/main/triagebot.toml", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": "\n [mentions.'foo/example1']\n cc = [\"@octocat\"]\n message = \"a custom message\"\n " +} \ No newline at end of file diff --git a/tests/server_test/mentions/custom_mention/02-webhook-push_0012b38544df09f2c18af8c92192366ee06913b0.json b/tests/server_test/mentions/custom_mention/02-webhook-push_0012b38544df09f2c18af8c92192366ee06913b0.json new file mode 100644 index 00000000..65344631 --- /dev/null +++ b/tests/server_test/mentions/custom_mention/02-webhook-push_0012b38544df09f2c18af8c92192366ee06913b0.json @@ -0,0 +1,190 @@ +{ + "kind": "Webhook", + "webhook_event": "push", + "payload": { + "after": "0012b38544df09f2c18af8c92192366ee06913b0", + "base_ref": null, + "before": "51f5007fddf25f6a92a0e35fafcf65de108050e5", + "commits": [ + { + "added": [ + "foo/example1" + ], + "author": { + "email": "eric@huss.org", + "name": "Eric Huss", + "username": "ehuss" + }, + "committer": { + "email": "eric@huss.org", + "name": "Eric Huss", + "username": "ehuss" + }, + "distinct": true, + "id": "0012b38544df09f2c18af8c92192366ee06913b0", + "message": "This is a test PR.", + "modified": [], + "removed": [], + "timestamp": "2023-03-07T18:40:15-08:00", + "tree_id": "98b523c06894137d7225f295f09b60e5fa8429b7", + "url": "https://github.com/ehuss/triagebot-test/commit/0012b38544df09f2c18af8c92192366ee06913b0" + } + ], + "compare": "https://github.com/ehuss/triagebot-test/compare/51f5007fddf2...0012b38544df", + "created": false, + "deleted": false, + "forced": true, + "head_commit": { + "added": [ + "foo/example1" + ], + "author": { + "email": "eric@huss.org", + "name": "Eric Huss", + "username": "ehuss" + }, + "committer": { + "email": "eric@huss.org", + "name": "Eric Huss", + "username": "ehuss" + }, + "distinct": true, + "id": "0012b38544df09f2c18af8c92192366ee06913b0", + "message": "This is a test PR.", + "modified": [], + "removed": [], + "timestamp": "2023-03-07T18:40:15-08:00", + "tree_id": "98b523c06894137d7225f295f09b60e5fa8429b7", + "url": "https://github.com/ehuss/triagebot-test/commit/0012b38544df09f2c18af8c92192366ee06913b0" + }, + "pusher": { + "email": "eric@huss.org", + "name": "ehuss" + }, + "ref": "refs/heads/mentions-test", + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": 1656279091, + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "master_branch": "main", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 9, + "open_issues_count": 9, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "email": "eric@huss.org", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "name": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": 1678243215, + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers": 0, + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://github.com/ehuss/triagebot-test", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/mentions/custom_mention/03-webhook-pr111_opened.json b/tests/server_test/mentions/custom_mention/03-webhook-pr111_opened.json new file mode 100644 index 00000000..cabe4d89 --- /dev/null +++ b/tests/server_test/mentions/custom_mention/03-webhook-pr111_opened.json @@ -0,0 +1,492 @@ +{ + "kind": "Webhook", + "webhook_event": "pull_request", + "payload": { + "action": "opened", + "number": 111, + "pull_request": { + "_links": { + "comments": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/issues/111/comments" + }, + "commits": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/111/commits" + }, + "html": { + "href": "https://github.com/ehuss/triagebot-test/pull/111" + }, + "issue": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/issues/111" + }, + "review_comment": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/comments{/number}" + }, + "review_comments": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/111/comments" + }, + "self": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/111" + }, + "statuses": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/statuses/0012b38544df09f2c18af8c92192366ee06913b0" + } + }, + "active_lock_reason": null, + "additions": 1, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "auto_merge": null, + "base": { + "label": "ehuss:main", + "ref": "main", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 9, + "open_issues_count": 9, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T02:40:16Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "bed2000c844b1552d9e39ef628071314a64160ad", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "body": "This is a test PR.", + "changed_files": 1, + "closed_at": null, + "comments": 0, + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/111/comments", + "commits": 1, + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/111/commits", + "created_at": "2023-03-08T02:40:16Z", + "deletions": 0, + "diff_url": "https://github.com/ehuss/triagebot-test/pull/111.diff", + "draft": false, + "head": { + "label": "ehuss:mentions-test", + "ref": "mentions-test", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 9, + "open_issues_count": 9, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T02:40:16Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "0012b38544df09f2c18af8c92192366ee06913b0", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "html_url": "https://github.com/ehuss/triagebot-test/pull/111", + "id": 1267250011, + "issue_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/111", + "labels": [], + "locked": false, + "maintainer_can_modify": false, + "merge_commit_sha": null, + "mergeable": null, + "mergeable_state": "unknown", + "merged": false, + "merged_at": null, + "merged_by": null, + "milestone": null, + "node_id": "PR_kwDOHkK3Xc5LiLNb", + "number": 111, + "patch_url": "https://github.com/ehuss/triagebot-test/pull/111.patch", + "rebaseable": null, + "requested_reviewers": [], + "requested_teams": [], + "review_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/comments{/number}", + "review_comments": 0, + "review_comments_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/111/comments", + "state": "open", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/0012b38544df09f2c18af8c92192366ee06913b0", + "title": "Test PR", + "updated_at": "2023-03-08T02:40:16Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/111", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 9, + "open_issues_count": 9, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T02:40:16Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/mentions/custom_mention/04-GET-repos_ehuss_triagebot-test_compare_bed2000c844b1552d9e39ef628071314a64160ad___0012b38544df09f2c18af8c92192366ee06913b0.json b/tests/server_test/mentions/custom_mention/04-GET-repos_ehuss_triagebot-test_compare_bed2000c844b1552d9e39ef628071314a64160ad___0012b38544df09f2c18af8c92192366ee06913b0.json new file mode 100644 index 00000000..96de18a1 --- /dev/null +++ b/tests/server_test/mentions/custom_mention/04-GET-repos_ehuss_triagebot-test_compare_bed2000c844b1552d9e39ef628071314a64160ad___0012b38544df09f2c18af8c92192366ee06913b0.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/ehuss/triagebot-test/compare/bed2000c844b1552d9e39ef628071314a64160ad...0012b38544df09f2c18af8c92192366ee06913b0", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": "diff --git a/foo/example1 b/foo/example1\nnew file mode 100644\nindex 0000000..679aa53\n--- /dev/null\n+++ b/foo/example1\n@@ -0,0 +1 @@\n+sample text\n\\ No newline at end of file\n" +} \ No newline at end of file diff --git a/tests/server_test/mentions/custom_mention/05-POST-repos_ehuss_triagebot-test_issues_111_comments.json b/tests/server_test/mentions/custom_mention/05-POST-repos_ehuss_triagebot-test_issues_111_comments.json new file mode 100644 index 00000000..52e6c48e --- /dev/null +++ b/tests/server_test/mentions/custom_mention/05-POST-repos_ehuss_triagebot-test_issues_111_comments.json @@ -0,0 +1,52 @@ +{ + "kind": "Request", + "method": "POST", + "path": "/repos/ehuss/triagebot-test/issues/111/comments", + "query": null, + "request_body": "{\"body\":\"a custom message\\n\\ncc @octocat\"}", + "response_code": 201, + "response_body": { + "author_association": "OWNER", + "body": "a custom message\n\ncc @octocat", + "created_at": "2023-03-08T02:40:17Z", + "html_url": "https://github.com/ehuss/triagebot-test/pull/111#issuecomment-1459205742", + "id": 1459205742, + "issue_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/111", + "node_id": "IC_kwDOHkK3Xc5W-bZu", + "performed_via_github_app": null, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments/1459205742/reactions" + }, + "updated_at": "2023-03-08T02:40:17Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments/1459205742", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?u=4e88d47bc79d87f09f463582681d29f1ed6f478e&v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/mentions/custom_mention/06-GET-v1_teams_json.json b/tests/server_test/mentions/custom_mention/06-GET-v1_teams_json.json new file mode 100644 index 00000000..25f6ff7d --- /dev/null +++ b/tests/server_test/mentions/custom_mention/06-GET-v1_teams_json.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/v1/teams.json", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": null +} \ No newline at end of file diff --git a/tests/server_test/mentions/custom_mention/07-webhook-issue111_comment_created.json b/tests/server_test/mentions/custom_mention/07-webhook-issue111_comment_created.json new file mode 100644 index 00000000..05ffb3fd --- /dev/null +++ b/tests/server_test/mentions/custom_mention/07-webhook-issue111_comment_created.json @@ -0,0 +1,239 @@ +{ + "kind": "Webhook", + "webhook_event": "issue_comment", + "payload": { + "action": "created", + "comment": { + "author_association": "OWNER", + "body": "a custom message\n\ncc @octocat", + "created_at": "2023-03-08T02:40:17Z", + "html_url": "https://github.com/ehuss/triagebot-test/pull/111#issuecomment-1459205742", + "id": 1459205742, + "issue_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/111", + "node_id": "IC_kwDOHkK3Xc5W-bZu", + "performed_via_github_app": null, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments/1459205742/reactions" + }, + "updated_at": "2023-03-08T02:40:17Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments/1459205742", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "issue": { + "active_lock_reason": null, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "body": "This is a test PR.", + "closed_at": null, + "comments": 1, + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/111/comments", + "created_at": "2023-03-08T02:40:16Z", + "draft": false, + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/111/events", + "html_url": "https://github.com/ehuss/triagebot-test/pull/111", + "id": 1614552536, + "labels": [], + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/111/labels{/name}", + "locked": false, + "milestone": null, + "node_id": "PR_kwDOHkK3Xc5LiLNb", + "number": 111, + "performed_via_github_app": null, + "pull_request": { + "diff_url": "https://github.com/ehuss/triagebot-test/pull/111.diff", + "html_url": "https://github.com/ehuss/triagebot-test/pull/111", + "merged_at": null, + "patch_url": "https://github.com/ehuss/triagebot-test/pull/111.patch", + "url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/111" + }, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/111/reactions" + }, + "repository_url": "https://api.github.com/repos/ehuss/triagebot-test", + "state": "open", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/111/timeline", + "title": "Test PR", + "updated_at": "2023-03-08T02:40:18Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/111", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 9, + "open_issues_count": 9, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T02:40:16Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/mentions/custom_mention/08-GET-v1_teams_json.json b/tests/server_test/mentions/custom_mention/08-GET-v1_teams_json.json new file mode 100644 index 00000000..25f6ff7d --- /dev/null +++ b/tests/server_test/mentions/custom_mention/08-GET-v1_teams_json.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/v1/teams.json", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": null +} \ No newline at end of file diff --git a/tests/server_test/mentions/custom_mention/09-GET-v1_teams_json.json b/tests/server_test/mentions/custom_mention/09-GET-v1_teams_json.json new file mode 100644 index 00000000..25f6ff7d --- /dev/null +++ b/tests/server_test/mentions/custom_mention/09-GET-v1_teams_json.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/v1/teams.json", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": null +} \ No newline at end of file diff --git a/tests/server_test/mentions/default_mention/00-webhook-pr108_closed.json b/tests/server_test/mentions/default_mention/00-webhook-pr108_closed.json new file mode 100644 index 00000000..2deb3fda --- /dev/null +++ b/tests/server_test/mentions/default_mention/00-webhook-pr108_closed.json @@ -0,0 +1,492 @@ +{ + "kind": "Webhook", + "webhook_event": "pull_request", + "payload": { + "action": "closed", + "number": 108, + "pull_request": { + "_links": { + "comments": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/issues/108/comments" + }, + "commits": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/108/commits" + }, + "html": { + "href": "https://github.com/ehuss/triagebot-test/pull/108" + }, + "issue": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/issues/108" + }, + "review_comment": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/comments{/number}" + }, + "review_comments": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/108/comments" + }, + "self": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/108" + }, + "statuses": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/statuses/49cbee26c8918fb9c96f27d3f7d8f8ed2124f56d" + } + }, + "active_lock_reason": null, + "additions": 1, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "auto_merge": null, + "base": { + "label": "ehuss:main", + "ref": "main", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T02:34:40Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "e20784d770c20107019708e622b33f3f97dce829", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "body": "This is a test PR.", + "changed_files": 1, + "closed_at": "2023-03-08T02:34:44Z", + "comments": 1, + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/108/comments", + "commits": 1, + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/108/commits", + "created_at": "2023-03-08T02:33:15Z", + "deletions": 0, + "diff_url": "https://github.com/ehuss/triagebot-test/pull/108.diff", + "draft": false, + "head": { + "label": "ehuss:mentions-test", + "ref": "mentions-test", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T02:34:40Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "49cbee26c8918fb9c96f27d3f7d8f8ed2124f56d", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "html_url": "https://github.com/ehuss/triagebot-test/pull/108", + "id": 1267243251, + "issue_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/108", + "labels": [], + "locked": false, + "maintainer_can_modify": false, + "merge_commit_sha": "5a877b766da619ef60e8d39a1b5d6e3c0d2c600a", + "mergeable": null, + "mergeable_state": "unknown", + "merged": false, + "merged_at": null, + "merged_by": null, + "milestone": null, + "node_id": "PR_kwDOHkK3Xc5LiJjz", + "number": 108, + "patch_url": "https://github.com/ehuss/triagebot-test/pull/108.patch", + "rebaseable": null, + "requested_reviewers": [], + "requested_teams": [], + "review_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/comments{/number}", + "review_comments": 0, + "review_comments_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/108/comments", + "state": "closed", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/49cbee26c8918fb9c96f27d3f7d8f8ed2124f56d", + "title": "Test PR", + "updated_at": "2023-03-08T02:34:44Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/108", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T02:34:40Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/mentions/default_mention/01-GET-ehuss_triagebot-test_main_triagebot_toml.json b/tests/server_test/mentions/default_mention/01-GET-ehuss_triagebot-test_main_triagebot_toml.json new file mode 100644 index 00000000..85fc83cd --- /dev/null +++ b/tests/server_test/mentions/default_mention/01-GET-ehuss_triagebot-test_main_triagebot_toml.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/ehuss/triagebot-test/main/triagebot.toml", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": "\n [mentions.'foo/example1']\n cc = [\"@octocat\"]\n " +} \ No newline at end of file diff --git a/tests/server_test/mentions/default_mention/02-webhook-push_9d584890ee0f093d15a62a75cf93cd9d8dcde1cc.json b/tests/server_test/mentions/default_mention/02-webhook-push_9d584890ee0f093d15a62a75cf93cd9d8dcde1cc.json new file mode 100644 index 00000000..980237cd --- /dev/null +++ b/tests/server_test/mentions/default_mention/02-webhook-push_9d584890ee0f093d15a62a75cf93cd9d8dcde1cc.json @@ -0,0 +1,190 @@ +{ + "kind": "Webhook", + "webhook_event": "push", + "payload": { + "after": "9d584890ee0f093d15a62a75cf93cd9d8dcde1cc", + "base_ref": null, + "before": "49cbee26c8918fb9c96f27d3f7d8f8ed2124f56d", + "commits": [ + { + "added": [ + "foo/example1" + ], + "author": { + "email": "eric@huss.org", + "name": "Eric Huss", + "username": "ehuss" + }, + "committer": { + "email": "eric@huss.org", + "name": "Eric Huss", + "username": "ehuss" + }, + "distinct": true, + "id": "9d584890ee0f093d15a62a75cf93cd9d8dcde1cc", + "message": "This is a test PR.", + "modified": [], + "removed": [], + "timestamp": "2023-03-07T18:34:45-08:00", + "tree_id": "7cf5d5ac5cfb361727c583ac0782a94cf2af4db5", + "url": "https://github.com/ehuss/triagebot-test/commit/9d584890ee0f093d15a62a75cf93cd9d8dcde1cc" + } + ], + "compare": "https://github.com/ehuss/triagebot-test/compare/49cbee26c891...9d584890ee0f", + "created": false, + "deleted": false, + "forced": true, + "head_commit": { + "added": [ + "foo/example1" + ], + "author": { + "email": "eric@huss.org", + "name": "Eric Huss", + "username": "ehuss" + }, + "committer": { + "email": "eric@huss.org", + "name": "Eric Huss", + "username": "ehuss" + }, + "distinct": true, + "id": "9d584890ee0f093d15a62a75cf93cd9d8dcde1cc", + "message": "This is a test PR.", + "modified": [], + "removed": [], + "timestamp": "2023-03-07T18:34:45-08:00", + "tree_id": "7cf5d5ac5cfb361727c583ac0782a94cf2af4db5", + "url": "https://github.com/ehuss/triagebot-test/commit/9d584890ee0f093d15a62a75cf93cd9d8dcde1cc" + }, + "pusher": { + "email": "eric@huss.org", + "name": "ehuss" + }, + "ref": "refs/heads/mentions-test", + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": 1656279091, + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "master_branch": "main", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "email": "eric@huss.org", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "name": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": 1678242886, + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers": 0, + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://github.com/ehuss/triagebot-test", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/mentions/default_mention/03-webhook-pr109_opened.json b/tests/server_test/mentions/default_mention/03-webhook-pr109_opened.json new file mode 100644 index 00000000..603d0598 --- /dev/null +++ b/tests/server_test/mentions/default_mention/03-webhook-pr109_opened.json @@ -0,0 +1,492 @@ +{ + "kind": "Webhook", + "webhook_event": "pull_request", + "payload": { + "action": "opened", + "number": 109, + "pull_request": { + "_links": { + "comments": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/issues/109/comments" + }, + "commits": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/109/commits" + }, + "html": { + "href": "https://github.com/ehuss/triagebot-test/pull/109" + }, + "issue": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/issues/109" + }, + "review_comment": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/comments{/number}" + }, + "review_comments": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/109/comments" + }, + "self": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/109" + }, + "statuses": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/statuses/9d584890ee0f093d15a62a75cf93cd9d8dcde1cc" + } + }, + "active_lock_reason": null, + "additions": 1, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "auto_merge": null, + "base": { + "label": "ehuss:main", + "ref": "main", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 9, + "open_issues_count": 9, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T02:34:47Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "692c7ad7fc472f6c08876611b22f4755dcbc189e", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "body": "This is a test PR.", + "changed_files": 1, + "closed_at": null, + "comments": 0, + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/109/comments", + "commits": 1, + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/109/commits", + "created_at": "2023-03-08T02:34:46Z", + "deletions": 0, + "diff_url": "https://github.com/ehuss/triagebot-test/pull/109.diff", + "draft": false, + "head": { + "label": "ehuss:mentions-test", + "ref": "mentions-test", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 9, + "open_issues_count": 9, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T02:34:47Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "9d584890ee0f093d15a62a75cf93cd9d8dcde1cc", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "html_url": "https://github.com/ehuss/triagebot-test/pull/109", + "id": 1267244964, + "issue_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/109", + "labels": [], + "locked": false, + "maintainer_can_modify": false, + "merge_commit_sha": null, + "mergeable": null, + "mergeable_state": "unknown", + "merged": false, + "merged_at": null, + "merged_by": null, + "milestone": null, + "node_id": "PR_kwDOHkK3Xc5LiJ-k", + "number": 109, + "patch_url": "https://github.com/ehuss/triagebot-test/pull/109.patch", + "rebaseable": null, + "requested_reviewers": [], + "requested_teams": [], + "review_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/comments{/number}", + "review_comments": 0, + "review_comments_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/109/comments", + "state": "open", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/9d584890ee0f093d15a62a75cf93cd9d8dcde1cc", + "title": "Test PR", + "updated_at": "2023-03-08T02:34:46Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/109", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 9, + "open_issues_count": 9, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T02:34:47Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/mentions/default_mention/04-GET-repos_ehuss_triagebot-test_compare_692c7ad7fc472f6c08876611b22f4755dcbc189e___9d584890ee0f093d15a62a75cf93cd9d8dcde1cc.json b/tests/server_test/mentions/default_mention/04-GET-repos_ehuss_triagebot-test_compare_692c7ad7fc472f6c08876611b22f4755dcbc189e___9d584890ee0f093d15a62a75cf93cd9d8dcde1cc.json new file mode 100644 index 00000000..5e256001 --- /dev/null +++ b/tests/server_test/mentions/default_mention/04-GET-repos_ehuss_triagebot-test_compare_692c7ad7fc472f6c08876611b22f4755dcbc189e___9d584890ee0f093d15a62a75cf93cd9d8dcde1cc.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/ehuss/triagebot-test/compare/692c7ad7fc472f6c08876611b22f4755dcbc189e...9d584890ee0f093d15a62a75cf93cd9d8dcde1cc", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": "diff --git a/foo/example1 b/foo/example1\nnew file mode 100644\nindex 0000000..679aa53\n--- /dev/null\n+++ b/foo/example1\n@@ -0,0 +1 @@\n+sample text\n\\ No newline at end of file\n" +} \ No newline at end of file diff --git a/tests/server_test/mentions/default_mention/05-POST-repos_ehuss_triagebot-test_issues_109_comments.json b/tests/server_test/mentions/default_mention/05-POST-repos_ehuss_triagebot-test_issues_109_comments.json new file mode 100644 index 00000000..5a116014 --- /dev/null +++ b/tests/server_test/mentions/default_mention/05-POST-repos_ehuss_triagebot-test_issues_109_comments.json @@ -0,0 +1,52 @@ +{ + "kind": "Request", + "method": "POST", + "path": "/repos/ehuss/triagebot-test/issues/109/comments", + "query": null, + "request_body": "{\"body\":\"Some changes occurred in foo/example1\\n\\ncc @octocat\"}", + "response_code": 201, + "response_body": { + "author_association": "OWNER", + "body": "Some changes occurred in foo/example1\n\ncc @octocat", + "created_at": "2023-03-08T02:34:48Z", + "html_url": "https://github.com/ehuss/triagebot-test/pull/109#issuecomment-1459196293", + "id": 1459196293, + "issue_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/109", + "node_id": "IC_kwDOHkK3Xc5W-ZGF", + "performed_via_github_app": null, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments/1459196293/reactions" + }, + "updated_at": "2023-03-08T02:34:48Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments/1459196293", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?u=4e88d47bc79d87f09f463582681d29f1ed6f478e&v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/mentions/default_mention/06-GET-v1_teams_json.json b/tests/server_test/mentions/default_mention/06-GET-v1_teams_json.json new file mode 100644 index 00000000..25f6ff7d --- /dev/null +++ b/tests/server_test/mentions/default_mention/06-GET-v1_teams_json.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/v1/teams.json", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": null +} \ No newline at end of file diff --git a/tests/server_test/mentions/default_mention/07-webhook-issue109_comment_created.json b/tests/server_test/mentions/default_mention/07-webhook-issue109_comment_created.json new file mode 100644 index 00000000..21b7e0d4 --- /dev/null +++ b/tests/server_test/mentions/default_mention/07-webhook-issue109_comment_created.json @@ -0,0 +1,239 @@ +{ + "kind": "Webhook", + "webhook_event": "issue_comment", + "payload": { + "action": "created", + "comment": { + "author_association": "OWNER", + "body": "Some changes occurred in foo/example1\n\ncc @octocat", + "created_at": "2023-03-08T02:34:48Z", + "html_url": "https://github.com/ehuss/triagebot-test/pull/109#issuecomment-1459196293", + "id": 1459196293, + "issue_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/109", + "node_id": "IC_kwDOHkK3Xc5W-ZGF", + "performed_via_github_app": null, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments/1459196293/reactions" + }, + "updated_at": "2023-03-08T02:34:48Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments/1459196293", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "issue": { + "active_lock_reason": null, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "body": "This is a test PR.", + "closed_at": null, + "comments": 1, + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/109/comments", + "created_at": "2023-03-08T02:34:46Z", + "draft": false, + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/109/events", + "html_url": "https://github.com/ehuss/triagebot-test/pull/109", + "id": 1614546808, + "labels": [], + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/109/labels{/name}", + "locked": false, + "milestone": null, + "node_id": "PR_kwDOHkK3Xc5LiJ-k", + "number": 109, + "performed_via_github_app": null, + "pull_request": { + "diff_url": "https://github.com/ehuss/triagebot-test/pull/109.diff", + "html_url": "https://github.com/ehuss/triagebot-test/pull/109", + "merged_at": null, + "patch_url": "https://github.com/ehuss/triagebot-test/pull/109.patch", + "url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/109" + }, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/109/reactions" + }, + "repository_url": "https://api.github.com/repos/ehuss/triagebot-test", + "state": "open", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/109/timeline", + "title": "Test PR", + "updated_at": "2023-03-08T02:34:49Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/109", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 9, + "open_issues_count": 9, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T02:34:47Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/mentions/default_mention/08-GET-v1_teams_json.json b/tests/server_test/mentions/default_mention/08-GET-v1_teams_json.json new file mode 100644 index 00000000..25f6ff7d --- /dev/null +++ b/tests/server_test/mentions/default_mention/08-GET-v1_teams_json.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/v1/teams.json", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": null +} \ No newline at end of file diff --git a/tests/server_test/mentions/default_mention/09-GET-v1_teams_json.json b/tests/server_test/mentions/default_mention/09-GET-v1_teams_json.json new file mode 100644 index 00000000..25f6ff7d --- /dev/null +++ b/tests/server_test/mentions/default_mention/09-GET-v1_teams_json.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/v1/teams.json", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": null +} \ No newline at end of file diff --git a/tests/server_test/mod.rs b/tests/server_test/mod.rs new file mode 100644 index 00000000..4cc3ed76 --- /dev/null +++ b/tests/server_test/mod.rs @@ -0,0 +1,670 @@ +//! Tests that exercise the webhook behavior of the triagebot server. +//! +//! These tests exercise the behavior of the `triagebot` server by injecting +//! webhook events into it, and then observing its behavior and response. They +//! involve setting up HTTP servers, launching the `triagebot` process, +//! injecting the webhook JSON object, and validating the result. +//! +//! The [`run_test`] function is used to set up the test and run it to +//! completion using pre-recorded JSON data. +//! +//! To write one of these tests, you'll need to use the recording function +//! against the live GitHub site to fetch what the actual JSON objects should +//! look like. To write a test, follow these steps: +//! +//! XXX +//! 1. Prepare a test repo on GitHub for exercising whatever action you want +//! to test (for example, your personal fork of `rust-lang/rust). Get +//! everything ready, such as opening a PR or whatever you need for your +//! test. +//! +//! 2. Manually launch the triagebot server with the `TRIAGEBOT_TEST_RECORD` +//! environment variable set to the path of where you want to store the +//! recorded JSON. Use a separate directory for each test. It may look +//! something like: +//! +//! ```sh +//! TRIAGEBOT_TEST_RECORD=server_test/shortcut/author cargo run --bin triagebot +//! ``` +//! +//! Look at `README.md` for instructions for running triagebot against the +//! live GitHub site. You'll need to have webhook forwarding running in the +//! background. +//! +//! 3. Perform the action you want to test on GitHub. For example, post a +//! comment with `@rustbot ready` to test the "ready" command. +//! +//! 4. Stop the triagebot server (hit CTRL-C or whatever). +//! +//! 5. The JSON for the interaction should now be stored in the directory. +//! Peruse the JSON to make sure the expected actions are there. +//! +//! 6. Add a test to replay that action you just performed. All you need to +//! do is call something like `run_test("shortcut/ready");` with the path +//! to the JSON (relative to the `server_test` directory). +//! +//! 7. Run your test to make sure it works: +//! +//! ```sh +//! cargo test --test testsuite -- server_test::shortcut::ready +//! ``` +//! +//! with the name of your test. +//! +//! ## Databases +//! +//! By default, the server tests will use Postgres if it is installed. If it +//! doesn't appear to be installed, then it will use SQLite instead. If you +//! want to force it to use SQLite, you can set the +//! TRIAGEBOT_TEST_FORCE_SQLITE environment variable. +//! +//! ## Scheduled Jobs +//! +//! Scheduled jobs get automatically disabled when recording or running tests +//! (via the `TRIAGEBOT_TEST_DISABLE_JOBS` environment variable). If you want +//! to write a test for a scheduled job, you'll need to set up a mechanism to +//! manually trigger the job (which could be useful outside of testing). + +mod mentions; +mod shortcut; + +use super::{HttpServer, HttpServerHandle}; +use futures::Future; +use std::io::Read; +use std::net::{SocketAddr, TcpListener}; +use std::path::PathBuf; +use std::process::{Child, Command, Stdio}; +use std::sync::atomic::AtomicU16; +use std::sync::{Arc, Mutex}; +use std::thread; +use std::time::Duration; +use triagebot::github::{GitTreeEntry, GithubClient, Issue, Repository}; +use triagebot::test_record::{self, Activity}; + +struct ServerTestSetup { + test_path: String, + gh: GithubClient, + repo: Repository, +} + +/// A context used for running a test. +/// +/// This is used for interacting with the triagebot process and handling API requests. +struct ServerTestCtx { + /// The triagebot process handle. + #[allow(dead_code)] // held for drop + triagebot_process: Process, + webhook_secret: String, + /// Directory for the temporary Postgres database. + /// + /// `None` if using sqlite. + db_dir: Option, + /// The address for sending webhooks into the triagebot binary. + triagebot_addr: SocketAddr, + /// The handle to the mock server which simulates GitHub. + #[allow(dead_code)] // held for drop + server: Option, + // TODO + gh: Option, + // TODO + repo: Option, + + #[allow(dead_code)] // held for drop + gh_process: Option, +} + +/// The main entry point for a test. +/// +/// Pass the name of the test as the first parameter. +fn run_test(test_path: &str, f: F) +where + F: Fn(ServerTestSetup) -> Fut + Send + Sync, + Fut: Future + Send, +{ + crate::assert_single_record(); + if std::env::var("TRIAGEBOT_TEST_RECORD").as_deref() == Ok("1") { + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap() + .block_on(async { + let repo_name = test_record::record_live_repo().expect( + "TRIAGEBOT_TEST_LIVE_REPO must be set to the GitHub test repo to \ + run tests on (\"username/reponame\" format)", + ); + dotenv::dotenv().ok(); + let gh = GithubClient::new_from_env(); + let repo = gh.repository(&repo_name).await.unwrap(); + let setup = ServerTestSetup { + test_path: test_path.into(), + gh, + repo, + }; + f(setup).await + }); + } else { + playback_test(test_path); + } +} + +fn playback_test(test_path: &str) { + let activities = crate::load_activities("tests/server_test", test_path); + if !matches!(activities[0], Activity::Webhook { .. }) { + panic!("expected first activity to be a webhook event"); + } + let ctx = ServerTestCtx::launch_prerecorded(activities); + // Wait for the server side to find a webhook. This will then send the + // webhook to the triagebot binary. + loop { + let activity = ctx + .server + .as_ref() + .unwrap() + .hook_recv + .recv_timeout(Duration::new(60, 0)) + .unwrap(); + match activity { + Activity::Webhook { + webhook_event, + payload, + } => { + eprintln!("sending webhook {webhook_event}"); + let payload = serde_json::to_vec(&payload).unwrap(); + ctx.send_webhook(&webhook_event, payload); + } + Activity::Error { message } => { + panic!("unexpected server error: {message}"); + } + Activity::Finished => break, + a => panic!("unexpected activity {a:?}"), + } + } +} + +impl ServerTestCtx { + fn launch_triagebot(server: Option, test_path: &str) -> ServerTestCtx { + let db_sqlite = || { + crate::test_dir() + .join("triagebot.sqlite3") + .to_str() + .unwrap() + .to_string() + }; + let (db_dir, database_url) = if std::env::var_os("TRIAGEBOT_TEST_FORCE_SQLITE").is_some() { + (None, db_sqlite()) + } else { + match crate::db::setup_postgres() { + Some(db_dir) => { + let database_url = crate::db::postgres_database_url(&db_dir); + (Some(db_dir), database_url) + } + None if std::env::var_os("CI").is_some() => panic!("expected postgres in CI"), + None => (None, db_sqlite()), + } + }; + + let triagebot_port = next_triagebot_port(); + let mut cmd = Command::new(env!("CARGO_BIN_EXE_triagebot")); + let rand_data: [u8; 8] = rand::random(); + let webhook_secret = hex::encode(&rand_data); + // TODO: Generate the secret + cmd.env("GITHUB_WEBHOOK_SECRET", &webhook_secret) + .env("DATABASE_URL", database_url) + .env("PORT", triagebot_port.to_string()) + // We don't want jobs randomly running while testing. + .env("TRIAGEBOT_TEST_DISABLE_JOBS", "1"); + if let Some(server) = &server { + // This is for replaying recorded data. + // Use a fake API token to ensure it doesn't try to contact the live server. + cmd.env( + "GITHUB_API_TOKEN", + "ghp_123456789012345678901234567890123456", + ) + .env("GITHUB_API_URL", format!("http://{}", server.addr)) + .env( + "GITHUB_GRAPHQL_API_URL", + format!("http://{}/graphql", server.addr), + ) + .env("GITHUB_RAW_URL", format!("http://{}", server.addr)) + .env("TEAMS_API_URL", format!("http://{}/v1", server.addr)); + } else { + // This is for recording data from the live server. + cmd.env("TRIAGEBOT_TEST_RECORD_DIR", format!("server_test/{test_path}")); + } + + let mut triagebot_process = Process::spawn(cmd); + let triagebot_addr = format!("127.0.0.1:{triagebot_port}").parse().unwrap(); + // Wait for the triagebot process to start up. + eprintln!("waiting for triagebot to be ready"); + let mut attempts = 0; + loop { + if attempts > 30 { + panic!("triagebot never responded"); + } + match std::net::TcpStream::connect(&triagebot_addr) { + Ok(_) => break, + Err(e) => match e.kind() { + std::io::ErrorKind::ConnectionRefused => { + std::thread::sleep(std::time::Duration::new(1, 0)) + } + _ => panic!("unexpected error testing triagebot connection: {e:?}"), + }, + } + if let Some(status) = triagebot_process.child.try_wait().unwrap() { + panic!("triagebot did not start: {status}"); + } + + attempts += 1; + } + ServerTestCtx { + triagebot_process, + webhook_secret, + db_dir, + triagebot_addr, + server, + gh: None, + repo: None, + gh_process: None, + } + } + + fn launch_prerecorded(activities: Vec) -> ServerTestCtx { + let server = HttpServer::new(activities); + ServerTestCtx::launch_triagebot(Some(server), "") + } + + /// Sends a webhook into the triagebot binary. + fn send_webhook(&self, event: &str, json: Vec) { + let hmac = triagebot::payload::sign(&self.webhook_secret, &json); + let sha1 = hex::encode(&hmac); + let client = reqwest::blocking::Client::new(); + let response = client + .post(format!("http://{}/github-hook", self.triagebot_addr)) + .header("X-GitHub-Event", event) + .header("X-Hub-Signature", format!("sha1={sha1}")) + .body(json) + .send() + .unwrap(); + if !response.status().is_success() { + let text = response.text().unwrap(); + panic!("webhook failed to get successful status: {text}"); + } + } +} + +impl Drop for ServerTestCtx { + fn drop(&mut self) { + if let Some(db_dir) = &self.db_dir { + crate::db::stop_postgres(db_dir); + } + } +} + +/// Returns a free port for the next triagebot process to use. +fn next_triagebot_port() -> u16 { + static NEXT_TCP_PORT: AtomicU16 = AtomicU16::new(50000); + loop { + // This depends on SO_REUSEADDR being set. + // + // This is inherently racey, as the port may become unavailable + // in-between the time it is checked here and triagebot actually binds + // to it. + // + // TODO: This may not work on Windows, may need investigation/fixing. + let triagebot_port = NEXT_TCP_PORT.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + if triagebot_port == 0 { + panic!("can't find port to listen on"); + } + if TcpListener::bind(format!("0.0.0.0:{triagebot_port}")).is_ok() { + return triagebot_port; + } + } +} + +impl ServerTestSetup { + pub async fn config(&self, config: &str) { + eprintln!("setting up triagebot.toml on {}", self.repo.full_name); + // Create a commit. + // Figure out the current head. + let default_head = format!("heads/{}", self.repo.default_branch); + let head_ref = self + .repo + .get_reference(&self.gh, &default_head) + .await + .unwrap(); + let head_commit = self + .repo + .git_commit(&self.gh, &head_ref.object.sha) + .await + .unwrap(); + // Create a blob for the commit. + let blob_sha = self + .repo + .create_blob(&self.gh, config, "utf-8") + .await + .unwrap(); + // Create a tree entry for this new file. + let tree_entries = vec![GitTreeEntry { + path: "triagebot.toml".into(), + mode: "100644".into(), + object_type: "blob".into(), + sha: Some(Some(blob_sha)), + content: None, + }]; + let new_tree = self + .repo + .update_tree(&self.gh, &head_commit.tree.sha, &tree_entries) + .await + .unwrap(); + + // Create a commit. + let commit = self + .repo + .create_commit( + &self.gh, + &format!("Set triagebot.toml config for {}", self.test_path), + &[&head_ref.object.sha], + &new_tree.sha, + ) + .await + .unwrap(); + // Move head to the new commit. + self.repo + .update_reference(&self.gh, &default_head, &commit.sha) + .await + .unwrap(); + } + + pub fn launch_triagebot_live(self) -> ServerTestCtx { + eprintln!("launching triagebot against live GitHub"); + let mut ctx = ServerTestCtx::launch_triagebot(None, &self.test_path); + // Launch webhook forwarding. + let mut gh_cmd = Command::new("gh"); + gh_cmd + .args(&["webhook", "forward", "--events=*"]) + .arg(format!("--repo={}", self.repo.full_name)) + .arg(format!("--url=http://{}/github-hook", ctx.triagebot_addr)) + .arg(format!("--secret={}", ctx.webhook_secret)); + let mut gh_process = Process::spawn(gh_cmd); + + // Wait for `gh` to launch and configure the repo. + eprintln!("waiting for gh webhook to be ready"); + let mut attempts = 0; + loop { + if attempts > 30 { + panic!("gh webhook doesn't appear to be ready"); + } + let stdout_lock = gh_process.stdout.lock().unwrap(); + let stdout = String::from_utf8_lossy(&stdout_lock); + if stdout.lines().any(|line| line.starts_with("Forwarding")) { + break; + } + drop(stdout_lock); + if let Some(status) = gh_process.child.try_wait().unwrap() { + panic!("gh webhook exited unexpectedly: {status}"); + } + std::thread::sleep(std::time::Duration::new(1, 0)); + attempts += 1; + } + ctx.gh = Some(self.gh); + ctx.repo = Some(self.repo); + ctx.gh_process = Some(gh_process); + ctx + } +} + +struct Process { + description: String, + child: Child, + stdout: Arc>>, + stderr: Arc>>, +} + +impl Process { + fn spawn(mut cmd: Command) -> Process { + let description = format!("{cmd:?}"); + let mut child = cmd + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .unwrap_or_else(|e| { + panic!( + "failed to spawn: `{description}`\n\ + {e}" + ); + }); + let stdout = Arc::new(Mutex::new(Vec::new())); + let stderr = Arc::new(Mutex::new(Vec::new())); + + let consumer = |mut source: Box, dest: Arc>>| { + move || loop { + let mut buffer = [0; 1024]; + match source.read(&mut buffer) { + Ok(n) if n == 0 => break, + Ok(n) => { + let mut dest = dest.lock().unwrap(); + dest.extend_from_slice(&buffer[0..n]); + } + Err(e) if e.kind() == std::io::ErrorKind::Interrupted => {} + Err(e) => { + eprintln!("failed to read output: {e}"); + return; + } + } + } + }; + thread::spawn(consumer( + Box::new(child.stdout.take().unwrap()), + stdout.clone(), + )); + thread::spawn(consumer( + Box::new(child.stderr.take().unwrap()), + stderr.clone(), + )); + + Process { + description, + child, + stdout, + stderr, + } + } +} + +impl Drop for Process { + fn drop(&mut self) { + let _ = self.child.kill(); + // Display output for debugging. + if let Ok(stderr) = self.stderr.lock() { + if let Ok(s) = std::str::from_utf8(&stderr) { + eprintln!("{} stdout:\n{s}", self.description); + } + } + if let Ok(stdout) = self.stdout.lock() { + if let Ok(s) = std::str::from_utf8(&stdout) { + eprintln!("{} stderr:\n{s}", self.description); + } + } + } +} + +struct TestPrBuilder { + title: String, + branch: String, + base: String, + message_body: String, + changes: Vec, +} + +impl TestPrBuilder { + fn new(branch: &str, base: &str) -> TestPrBuilder { + TestPrBuilder { + title: "Test PR".into(), + branch: branch.into(), + base: base.into(), + message_body: "This is a test PR.".into(), + changes: Vec::new(), + } + } + + pub fn file(mut self, path: &str, executable: bool, content: &str) -> Self { + self.changes.push(TestPrChange::File { + path: path.into(), + executable, + content: content.into(), + }); + self + } + + pub fn rm_file(mut self, path: &str) -> Self { + self.changes + .push(TestPrChange::RemoveFile { path: path.into() }); + self + } + + pub fn submodule(mut self, path: &str, commit: &str) -> Self { + self.changes.push(TestPrChange::Submodule { + path: path.into(), + commit: commit.into(), + }); + self + } + + pub fn symlink(mut self, path: &str, dest: &str) -> Self { + self.changes.push(TestPrChange::Symlink { + path: path.into(), + dest: dest.into(), + }); + self + } + + pub async fn create(mut self, gh: &GithubClient, repo: &Repository) -> Issue { + // Delete any PRs open for this branch (GitHub does not allow multiple + // PRs to the same branch). + close_opened_prs(gh, repo, &self.branch).await; + + // Create a commit. + // Figure out the current head. + let head_ref = repo + .get_reference(gh, &format!("heads/{}", self.base)) + .await + .unwrap(); + let head_commit = repo.git_commit(gh, &head_ref.object.sha).await.unwrap(); + // Create blobs for new/modified files. + if self.changes.is_empty() { + self = self.file("sample-file.md", false, "This is some sample text"); + } + let tree_entries: Vec<_> = self + .changes + .into_iter() + .map(TestPrChange::into_tree_entry) + .collect(); + let new_tree = repo + .update_tree(gh, &head_commit.tree.sha, &tree_entries) + .await + .unwrap(); + + let commit = repo + .create_commit( + gh, + &self.message_body, + &[&head_ref.object.sha], + &new_tree.sha, + ) + .await + .unwrap(); + // Set the branch to that commit. + repo.create_or_update_reference(gh, &format!("heads/{}", self.branch), &commit.sha) + .await + .unwrap(); + // Create a pull request. + repo.new_pr( + gh, + &self.title, + &self.branch, + &self.base, + &self.message_body, + ) + .await + .unwrap() + } +} + +enum TestPrChange { + File { + path: String, + executable: bool, + content: String, + }, + RemoveFile { + path: String, + }, + Submodule { + path: String, + commit: String, + }, + Symlink { + path: String, + dest: String, + }, +} + +impl TestPrChange { + fn into_tree_entry(self) -> GitTreeEntry { + match self { + TestPrChange::File { + path, + executable, + content, + } => { + let mode = if executable { "100755" } else { "100644" }.into(); + GitTreeEntry { + path, + mode, + object_type: "blob".into(), + sha: None, + content: Some(content), + } + } + TestPrChange::RemoveFile { path } => GitTreeEntry { + path, + mode: "100644".into(), + object_type: "blob".into(), + sha: Some(None), + content: None, + }, + TestPrChange::Submodule { path, commit } => GitTreeEntry { + path, + mode: "160000".into(), + object_type: "commit".into(), + sha: Some(Some(commit)), + content: None, + }, + TestPrChange::Symlink { path, dest } => GitTreeEntry { + path, + mode: "120000".into(), + object_type: "blob".into(), + sha: None, + content: Some(dest), + }, + } + } +} + +pub async fn close_opened_prs(gh: &GithubClient, repo: &Repository, branch: &str) { + let issues = repo + .get_prs( + gh, + "open", + Some(&format!("{}:{}", repo.full_name, branch)), + Some(&repo.default_branch), + None, + None, + ) + .await + .unwrap(); + for issue in issues { + eprintln!("closing PR {}", issue.number); + issue.close(gh).await.unwrap(); + } +} diff --git a/tests/server_test/shared/teams.json b/tests/server_test/shared/teams.json new file mode 100644 index 00000000..f50def09 --- /dev/null +++ b/tests/server_test/shared/teams.json @@ -0,0 +1,11283 @@ +{ + "all": { + "name": "all", + "kind": "team", + "subteam_of": null, + "members": [ + { + "name": "Aaron Hill", + "github": "Aaron1011", + "github_id": 1408859, + "is_lead": false + }, + { + "name": "Aditya Arora", + "github": "adityac8", + "github_id": 19192257, + "is_lead": false + }, + { + "name": "Nixon Enraght-Moony", + "github": "aDotInTheVoid", + "github_id": 28781354, + "is_lead": false + }, + { + "name": "Albert Larsan", + "github": "albertlarsan68", + "github_id": 74931857, + "is_lead": false + }, + { + "name": "Alex Crichton", + "github": "alexcrichton", + "github_id": 64996, + "is_lead": false + }, + { + "name": "Alex Macleod", + "github": "Alexendoo", + "github_id": 1830331, + "is_lead": false + }, + { + "name": "Alex Butler", + "github": "alexheretic", + "github_id": 2331607, + "is_lead": false + }, + { + "name": "Amanieu d'Antras", + "github": "Amanieu", + "github_id": 278509, + "is_lead": false + }, + { + "name": "andrewpollack", + "github": "andrewpollack", + "github_id": 24868505, + "is_lead": false + }, + { + "name": "Forest Anderson", + "github": "AngelOnFira", + "github_id": 14791619, + "is_lead": false + }, + { + "name": "Arshia Mufti", + "github": "arshiamufti", + "github_id": 15066212, + "is_lead": false + }, + { + "name": "Junfeng Li", + "github": "autozimu", + "github_id": 1453551, + "is_lead": false + }, + { + "name": "Jan-Erik Rediger", + "github": "badboy", + "github_id": 2129, + "is_lead": false + }, + { + "name": "benny Vasquez", + "github": "bennyvasquez", + "github_id": 13630986, + "is_lead": false + }, + { + "name": "bjorn3", + "github": "bjorn3", + "github_id": 17426603, + "is_lead": false + }, + { + "name": "Boxy", + "github": "BoxyUwU", + "github_id": 21149742, + "is_lead": false + }, + { + "name": "Andrew Gallant", + "github": "BurntSushi", + "github_id": 456674, + "is_lead": false + }, + { + "name": "Sebastian Thiel", + "github": "Byron", + "github_id": 63622, + "is_lead": false + }, + { + "name": "Caleb Cartwright", + "github": "calebcartwright", + "github_id": 13042488, + "is_lead": false + }, + { + "name": "Noah Lev", + "github": "camelid", + "github_id": 37223377, + "is_lead": false + }, + { + "name": "Cameron Steffen", + "github": "camsteffen", + "github_id": 5565418, + "is_lead": false + }, + { + "name": "Carol Nichols", + "github": "carols10cents", + "github_id": 193874, + "is_lead": false + }, + { + "name": "Colton Donnelly", + "github": "cdmistman", + "github_id": 23486351, + "is_lead": false + }, + { + "name": "Claus Matzinger", + "github": "celaus", + "github_id": 713346, + "is_lead": false + }, + { + "name": "Chris Denton", + "github": "ChrisDenton", + "github_id": 4459874, + "is_lead": false + }, + { + "name": "Camille Gillot", + "github": "cjgillot", + "github_id": 1822483, + "is_lead": false + }, + { + "name": "Michael Goulet", + "github": "compiler-errors", + "github_id": 3674314, + "is_lead": false + }, + { + "name": "Taylor Cramer", + "github": "cramertj", + "github_id": 5963049, + "is_lead": false + }, + { + "name": "Josh Stone", + "github": "cuviper", + "github_id": 36186, + "is_lead": false + }, + { + "name": "David Wood", + "github": "davidtwco", + "github_id": 1295100, + "is_lead": false + }, + { + "name": "dswij", + "github": "dswij", + "github_id": 44697459, + "is_lead": false + }, + { + "name": "David Tolnay", + "github": "dtolnay", + "github_id": 1940490, + "is_lead": false + }, + { + "name": "Dylan DPC", + "github": "Dylan-DPC", + "github_id": 99973273, + "is_lead": false + }, + { + "name": "Dylan MacKenzie", + "github": "ecstatic-morse", + "github_id": 29463364, + "is_lead": false + }, + { + "name": "Eduard-Mihai Burtescu", + "github": "eddyb", + "github_id": 77424, + "is_lead": false + }, + { + "name": "Jacob Finkelman", + "github": "Eh2406", + "github_id": 3709504, + "is_lead": false + }, + { + "name": "Eric Holk", + "github": "eholk", + "github_id": 105766, + "is_lead": false + }, + { + "name": "Eric Huss", + "github": "ehuss", + "github_id": 43198, + "is_lead": false + }, + { + "name": "Ed Page", + "github": "epage", + "github_id": 60961, + "is_lead": false + }, + { + "name": "Eric Seppanen", + "github": "ericseppanen", + "github_id": 36317762, + "is_lead": false + }, + { + "name": "Esteban Kuber", + "github": "estebank", + "github_id": 1606434, + "is_lead": false + }, + { + "name": "Stephan D.", + "github": "extrawurst", + "github_id": 776816, + "is_lead": false + }, + { + "name": "Deadbeef", + "github": "fee1-dead", + "github_id": 43851243, + "is_lead": false + }, + { + "name": "Nick Fitzgerald", + "github": "fitzgen", + "github_id": 74571, + "is_lead": false + }, + { + "name": "István Szmozsánszky", + "github": "flaki", + "github_id": 2089432, + "is_lead": false + }, + { + "name": "Philipp Krones", + "github": "flip1995", + "github_id": 9744647, + "is_lead": false + }, + { + "name": "Florian Diebold", + "github": "flodiebold", + "github_id": 906069, + "is_lead": false + }, + { + "name": "Alexis Beingessner", + "github": "Gankra", + "github_id": 1136864, + "is_lead": false + }, + { + "name": "Takayuki Nakata", + "github": "giraffate", + "github_id": 17407489, + "is_lead": false + }, + { + "name": "Guillaume Gomez", + "github": "GuillaumeGomez", + "github_id": 3050060, + "is_lead": false + }, + { + "name": "Ryan Scheel", + "github": "Havvy", + "github_id": 731722, + "is_lead": false + }, + { + "name": "二手掉包工程师", + "github": "hi-rustin", + "github_id": 29879298, + "is_lead": false + }, + { + "name": "Jack Huey", + "github": "jackh726", + "github_id": 31162821, + "is_lead": false + }, + { + "name": "Jakob Degen", + "github": "JakobDegen", + "github_id": 51179609, + "is_lead": false + }, + { + "name": "Jason Newcomb", + "github": "Jarcho", + "github_id": 7761774, + "is_lead": false + }, + { + "name": "Jason Williams", + "github": "jasonwilliams", + "github_id": 936006, + "is_lead": false + }, + { + "name": "Jan David Nose", + "github": "jdno", + "github_id": 865550, + "is_lead": false + }, + { + "name": "JT", + "github": "jntrnr", + "github_id": 547158, + "is_lead": false + }, + { + "name": "Joel Marcey", + "github": "JoelMarcey", + "github_id": 3757713, + "is_lead": false + }, + { + "name": "Yuki Okushi", + "github": "JohnTitor", + "github_id": 25030997, + "is_lead": false + }, + { + "name": "Jonas Schievink", + "github": "jonas-schievink", + "github_id": 1786438, + "is_lead": false + }, + { + "name": "Josh Triplett", + "github": "joshtriplett", + "github_id": 162737, + "is_lead": false + }, + { + "name": "Jacob Hoffman-Andrews", + "github": "jsha", + "github_id": 220205, + "is_lead": false + }, + { + "name": "Justin Geibel", + "github": "jtgeibel", + "github_id": 22186, + "is_lead": false + }, + { + "name": "Joshua Nelson", + "github": "jyn514", + "github_id": 23638587, + "is_lead": false + }, + { + "name": "kennytm", + "github": "kennytm", + "github_id": 103023, + "is_lead": false + }, + { + "name": "Khionu Sybiern", + "github": "khionu", + "github_id": 11195266, + "is_lead": false + }, + { + "name": "Daniel Silverstone", + "github": "kinnison", + "github_id": 1469421, + "is_lead": false + }, + { + "name": "Jakub Beránek", + "github": "Kobzol", + "github_id": 4539057, + "is_lead": false + }, + { + "name": "Ashley Mannix", + "github": "KodrAus", + "github_id": 6721458, + "is_lead": false + }, + { + "name": "lcnr", + "github": "lcnr", + "github_id": 29864074, + "is_lead": false + }, + { + "name": "Andre Bogus", + "github": "llogiq", + "github_id": 4200835, + "is_lead": false + }, + { + "name": "Ricardo Mendes", + "github": "locks", + "github_id": 32344, + "is_lead": false + }, + { + "name": "Rémy Rakic", + "github": "lqd", + "github_id": 247183, + "is_lead": false + }, + { + "name": "Lucas Bullen", + "github": "LucasBullen", + "github_id": 10255066, + "is_lead": false + }, + { + "name": "Mara Bos", + "github": "m-ou-se", + "github_id": 783247, + "is_lead": false + }, + { + "name": "Manish Goregaokar", + "github": "Manishearth", + "github_id": 1617736, + "is_lead": false + }, + { + "name": "M Goldin", + "github": "mariannegoldin", + "github_id": 23177337, + "is_lead": false + }, + { + "name": "Mark Rousskov", + "github": "Mark-Simulacrum", + "github_id": 5047365, + "is_lead": false + }, + { + "name": "Aleksey Kladov", + "github": "matklad", + "github_id": 1711539, + "is_lead": false + }, + { + "name": "Matt Gathu", + "github": "mattgathu", + "github_id": 1155192, + "is_lead": false + }, + { + "name": "Matthew Jasper", + "github": "matthewjasper", + "github_id": 20113453, + "is_lead": false + }, + { + "name": "Matthias Krüger", + "github": "matthiaskrgr", + "github_id": 476013, + "is_lead": false + }, + { + "name": "Michael Woerister", + "github": "michaelwoerister", + "github_id": 1825894, + "is_lead": false + }, + { + "name": "Nadrieril", + "github": "Nadrieril", + "github_id": 6783654, + "is_lead": false + }, + { + "name": "Simonas Kazlauskas", + "github": "nagisa", + "github_id": 679122, + "is_lead": false + }, + { + "name": "Nell Shamrell-Harrington", + "github": "nellshamrell", + "github_id": 813007, + "is_lead": false + }, + { + "name": "Wim", + "github": "Nemo157", + "github_id": 81079, + "is_lead": false + }, + { + "name": "Nikita Popov", + "github": "nikic", + "github_id": 216080, + "is_lead": false + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": false + }, + { + "name": "nils", + "github": "Nilstrieb", + "github_id": 48135649, + "is_lead": false + }, + { + "name": "Nicholas Nethercote", + "github": "nnethercote", + "github_id": 1940286, + "is_lead": false + }, + { + "name": "Michael Howell", + "github": "notriddle", + "github_id": 1593513, + "is_lead": false + }, + { + "name": "Nick Cameron", + "github": "nrc", + "github_id": 762626, + "is_lead": false + }, + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": false + }, + { + "name": "Onur Özkan", + "github": "ozkanonur", + "github_id": 39852038, + "is_lead": false + }, + { + "name": "Vadim Petrochenkov", + "github": "petrochenkov", + "github_id": 5751617, + "is_lead": false + }, + { + "name": "Florian Pichler", + "github": "pichfl", + "github_id": 194641, + "is_lead": false + }, + { + "name": "Pietro Albini", + "github": "pietroalbini", + "github_id": 2299951, + "is_lead": false + }, + { + "name": "Felix Klock", + "github": "pnkfelix", + "github_id": 173127, + "is_lead": false + }, + { + "name": "Ralf Jung", + "github": "RalfJung", + "github_id": 330628, + "is_lead": false + }, + { + "name": "Robert Collins", + "github": "rbtcollins", + "github_id": 499678, + "is_lead": false + }, + { + "name": "Ryan Levick", + "github": "rylev", + "github_id": 1327285, + "is_lead": false + }, + { + "name": "Ben Kimock", + "github": "saethlin", + "github_id": 12105168, + "is_lead": false + }, + { + "name": "Alexandre Martin", + "github": "scalexm", + "github_id": 1173131, + "is_lead": false + }, + { + "name": "Scott McMurray", + "github": "scottmcm", + "github_id": 18526288, + "is_lead": false + }, + { + "name": "Sebastián Magrí", + "github": "sebasmagri", + "github_id": 11137, + "is_lead": false + }, + { + "name": "Sage Griffin", + "github": "sgrif", + "github_id": 1529387, + "is_lead": false + }, + { + "name": "Liv", + "github": "shadows-withal", + "github_id": 6445316, + "is_lead": false + }, + { + "name": "Jake Goulding", + "github": "shepmaster", + "github_id": 174509, + "is_lead": false + }, + { + "name": "Simon Sapin", + "github": "SimonSapin", + "github_id": 291359, + "is_lead": false + }, + { + "name": "Sven Marnach", + "github": "smarnach", + "github_id": 249196, + "is_lead": false + }, + { + "name": "Katharina Fey", + "github": "spacekookie", + "github_id": 7669898, + "is_lead": false + }, + { + "name": "Santiago Pastorino", + "github": "spastorino", + "github_id": 52642, + "is_lead": false + }, + { + "name": "Dan Gohman", + "github": "sunfishcode", + "github_id": 4503403, + "is_lead": false + }, + { + "name": "Denis Cornehl", + "github": "syphar", + "github_id": 540890, + "is_lead": false + }, + { + "name": "Takayuki Maeda", + "github": "TaKO8Ki", + "github_id": 41065217, + "is_lead": false + }, + { + "name": "Olive Gould", + "github": "technetos", + "github_id": 10949810, + "is_lead": false + }, + { + "name": "The 8472", + "github": "the8472", + "github_id": 1065730, + "is_lead": false + }, + { + "name": "Thom Chiovoloni", + "github": "thomcc", + "github_id": 860665, + "is_lead": false + }, + { + "name": "Tyler Mandry", + "github": "tmandry", + "github_id": 2280544, + "is_lead": false + }, + { + "name": "tmiasko", + "github": "tmiasko", + "github_id": 51362316, + "is_lead": false + }, + { + "name": "Tobias Bieniek", + "github": "Turbo87", + "github_id": 141300, + "is_lead": false + }, + { + "name": "Brad Gibson", + "github": "U007D", + "github_id": 2874989, + "is_lead": false + }, + { + "name": "varkor", + "github": "varkor", + "github_id": 3943692, + "is_lead": false + }, + { + "name": "Mahmut Bulut", + "github": "vertexclique", + "github_id": 578559, + "is_lead": false + }, + { + "name": "Vlad Beskrovnyy", + "github": "vlad20012", + "github_id": 3221931, + "is_lead": false + }, + { + "name": "Waffle Maybe", + "github": "WaffleLapkin", + "github_id": 38225716, + "is_lead": false + }, + { + "name": "Weihang Lo", + "github": "weihanglo", + "github_id": 14314532, + "is_lead": false + }, + { + "name": "Wesley Wiser", + "github": "wesleywiser", + "github_id": 831192, + "is_lead": false + }, + { + "name": "Wesley Moore", + "github": "wezm", + "github_id": 21787, + "is_lead": false + }, + { + "name": "Jubilee", + "github": "workingjubilee", + "github_id": 46493976, + "is_lead": false + }, + { + "name": "Igor Matuszewski", + "github": "Xanewok", + "github_id": 3093213, + "is_lead": false + }, + { + "name": "Fridtjof Stoldt", + "github": "xFrednet", + "github_id": 17087237, + "is_lead": false + }, + { + "name": "Jane Lusby", + "github": "yaahc", + "github_id": 1993852, + "is_lead": false + }, + { + "name": "Yacin Tmimi", + "github": "ytmimi", + "github_id": 29028348, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "all", + "members": [ + 1408859, + 1830331, + 278509, + 14791619, + 21149742, + 456674, + 63622, + 4459874, + 99973273, + 3709504, + 1136864, + 3050060, + 731722, + 51179609, + 7761774, + 3757713, + 25030997, + 4539057, + 6721458, + 10255066, + 1617736, + 5047365, + 6783654, + 81079, + 48135649, + 330628, + 291359, + 41065217, + 141300, + 2874989, + 38225716, + 3093213, + 28781354, + 19192257, + 74931857, + 64996, + 2331607, + 24868505, + 15066212, + 1453551, + 2129, + 13630986, + 17426603, + 13042488, + 37223377, + 5565418, + 193874, + 23486351, + 713346, + 1822483, + 3674314, + 5963049, + 36186, + 1295100, + 44697459, + 1940490, + 29463364, + 77424, + 105766, + 43198, + 60961, + 36317762, + 1606434, + 776816, + 43851243, + 74571, + 2089432, + 9744647, + 906069, + 17407489, + 29879298, + 31162821, + 936006, + 865550, + 547158, + 1786438, + 162737, + 220205, + 22186, + 23638587, + 103023, + 11195266, + 1469421, + 29864074, + 4200835, + 32344, + 247183, + 783247, + 23177337, + 1711539, + 1155192, + 20113453, + 476013, + 1825894, + 679122, + 813007, + 216080, + 155238, + 1940286, + 1593513, + 762626, + 332036, + 39852038, + 5751617, + 194641, + 2299951, + 173127, + 499678, + 1327285, + 12105168, + 1173131, + 18526288, + 11137, + 1529387, + 6445316, + 174509, + 249196, + 7669898, + 52642, + 4503403, + 540890, + 10949810, + 1065730, + 860665, + 2280544, + 51362316, + 3943692, + 578559, + 3221931, + 14314532, + 831192, + 21787, + 46493976, + 17087237, + 1993852, + 29028348 + ] + } + ] + }, + "website_data": null, + "discord": [ + { + "name": "WGs and Teams", + "members": [ + 635351653226381333, + 412702990072283138, + 300421337103466496, + 232888196063690752, + 296309029947441155, + 1067068563938095134, + 382886245069488129, + 568772690438127647, + 83124738867597312, + 446765297286774784, + 278623213448331265, + 391665108490649601, + 972581951082999898, + 388091358901960705, + 442067131769683974, + 362122860673892353, + 453958363152252928, + 278605906332221441, + 771650879836127232, + 414755070161453076, + 442403469580566528, + 282164774379192320, + 446773566478745611, + 521108621115916298, + 244302461718757376, + 96642168176807936, + 443810603417731092, + 707155612672196689, + 133358326439346176, + 818556851112902657, + 453980540824059918, + 443061971114262528, + 347670185806659585, + 301677135293186049, + 491002025950183434, + 434359017515646988, + 401012249436749834, + 451800670635294731, + 446730792933130242, + 123482303698567168, + 443825361256448003, + 119181581033275392, + 313625269405745155, + 449245991216873475, + 468253584421552139, + 953562944472510494, + 274907435972427778, + 451522714101088258, + 218496229808668672 + ], + "color": null + } + ] + }, + "alumni": { + "name": "alumni", + "kind": "team", + "subteam_of": null, + "members": [ + { + "name": "James Miller", + "github": "Aatch", + "github_id": 342416, + "is_lead": false + }, + { + "name": "Aidan Hobson Sayers", + "github": "aidanhs", + "github_id": 1050652, + "is_lead": false + }, + { + "name": "Alexis Hunt", + "github": "alercah", + "github_id": 20842325, + "is_lead": false + }, + { + "name": "Amanjeev Sethi", + "github": "amanjeev", + "github_id": 160476, + "is_lead": false + }, + { + "name": "Michael Babenko", + "github": "Areredify", + "github_id": 25266609, + "is_lead": false + }, + { + "name": "Ariel Ben-Yehuda", + "github": "arielb1", + "github_id": 1830974, + "is_lead": false + }, + { + "name": "Ashley Williams", + "github": "ashleygwilliams", + "github_id": 1163554, + "is_lead": false + }, + { + "name": "Aaron Turon", + "github": "aturon", + "github_id": 709807, + "is_lead": false + }, + { + "name": "Diane Hosfelt", + "github": "avadacatavra", + "github_id": 11877868, + "is_lead": false + }, + { + "name": "awygle", + "github": "awygle", + "github_id": 7854806, + "is_lead": false + }, + { + "name": "Mark Drobnak", + "github": "AzureMarker", + "github_id": 4417660, + "is_lead": false + }, + { + "name": "Ben Lewis", + "github": "BenLewis-Seequent", + "github_id": 7391596, + "is_lead": false + }, + { + "name": "Didrik Nordström", + "github": "betamos", + "github_id": 135960, + "is_lead": false + }, + { + "name": "Bhargav Voleti", + "github": "bIgBV", + "github_id": 5019938, + "is_lead": false + }, + { + "name": "Georg Brandl", + "github": "birkenfeld", + "github_id": 144359, + "is_lead": false + }, + { + "name": "Brian Koropoff", + "github": "bkoropoff", + "github_id": 2101303, + "is_lead": false + }, + { + "name": "Mark Sta Ana", + "github": "booyaa", + "github_id": 192864, + "is_lead": false + }, + { + "name": "Brad Campbell", + "github": "bradjc", + "github_id": 1467890, + "is_lead": false + }, + { + "name": "Brian Anderson", + "github": "brson", + "github_id": 147214, + "is_lead": false + }, + { + "name": "Mazdak Farrokhzad", + "github": "Centril", + "github_id": 855702, + "is_lead": false + }, + { + "name": "Jakob Wiesmore", + "github": "CraftSpider", + "github_id": 13342132, + "is_lead": false + }, + { + "name": "csmoe", + "github": "csmoe", + "github_id": 35686186, + "is_lead": false + }, + { + "name": "Dan Callaghan", + "github": "danc86", + "github_id": 398575, + "is_lead": false + }, + { + "name": "Daniel Henry-Mantilla", + "github": "danielhenrymantilla", + "github_id": 9920355, + "is_lead": false + }, + { + "name": "Wilco Kusee", + "github": "detrumi", + "github_id": 5758008, + "is_lead": false + }, + { + "name": "Björn Steinbrink", + "github": "dotdash", + "github_id": 230962, + "is_lead": false + }, + { + "name": "David Craven", + "github": "dvc94ch", + "github_id": 741807, + "is_lead": false + }, + { + "name": "Dale Wijnand", + "github": "dwijnand", + "github_id": 344610, + "is_lead": false + }, + { + "name": "Dylan McKay", + "github": "dylanmckay", + "github_id": 7722159, + "is_lead": false + }, + { + "name": "Eduardo Broto", + "github": "ebroto", + "github_id": 816908, + "is_lead": false + }, + { + "name": "E. Dunham", + "github": "edunham", + "github_id": 812892, + "is_lead": false + }, + { + "name": "Andrew Chin", + "github": "eminence", + "github_id": 402454, + "is_lead": false + }, + { + "name": "Emmanuel Antony", + "github": "emmanuelantony2000", + "github_id": 19288251, + "is_lead": false + }, + { + "name": "Erick Tryzelaar", + "github": "erickt", + "github_id": 84711, + "is_lead": false + }, + { + "name": "Corey Farwell", + "github": "frewsxcv", + "github_id": 416575, + "is_lead": false + }, + { + "name": "Squirrel", + "github": "gilescope", + "github_id": 803976, + "is_lead": false + }, + { + "name": "Benjamin Kampmann", + "github": "gnunicorn", + "github_id": 40496, + "is_lead": false + }, + { + "name": "Hanna Kruppe", + "github": "hanna-kruppe", + "github_id": 2311707, + "is_lead": false + }, + { + "name": "Hanno Braun", + "github": "hannobraun", + "github_id": 85732, + "is_lead": false + }, + { + "name": "Huon Wilson", + "github": "huonw", + "github_id": 1203825, + "is_lead": false + }, + { + "name": "Tatsuyuki Ishi", + "github": "ishitatsuyuki", + "github_id": 12389383, + "is_lead": false + }, + { + "name": "Jonathan Soo", + "github": "jcsoo", + "github_id": 2399463, + "is_lead": false + }, + { + "name": "Jeffrey Seyfried", + "github": "jseyfried", + "github_id": 8652869, + "is_lead": false + }, + { + "name": "Marvin Löbel", + "github": "Kimundi", + "github_id": 2903206, + "is_lead": false + }, + { + "name": "Chase Wilson", + "github": "Kixiron", + "github_id": 25047011, + "is_lead": false + }, + { + "name": "Emil Fresk", + "github": "korken89", + "github_id": 913109, + "is_lead": false + }, + { + "name": "Wladimir J. van der Laan", + "github": "laanwj", + "github_id": 126646, + "is_lead": false + }, + { + "name": "Lee Bernick", + "github": "lbernick", + "github_id": 29333301, + "is_lead": false + }, + { + "name": "Léo Lanteri Thauvin", + "github": "LeSeulArtichaut", + "github_id": 38361244, + "is_lead": false + }, + { + "name": "Levente Kurusa", + "github": "levex", + "github_id": 849140, + "is_lead": false + }, + { + "name": "Lucio Franco", + "github": "LucioFranco", + "github_id": 5758045, + "is_lead": false + }, + { + "name": "Lukas Kalbertodt", + "github": "LukasKalbertodt", + "github_id": 7419664, + "is_lead": false + }, + { + "name": "Josef Brandl", + "github": "MajorBreakfast", + "github_id": 340142, + "is_lead": false + }, + { + "name": "Who? Me?!", + "github": "mark-i-m", + "github_id": 8827840, + "is_lead": false + }, + { + "name": "Mark McCaskey", + "github": "MarkMcCaskey", + "github_id": 5770194, + "is_lead": false + }, + { + "name": "Matthieu M.", + "github": "matthieu-m", + "github_id": 2420441, + "is_lead": false + }, + { + "name": "Matt Brubeck", + "github": "mbrubeck", + "github_id": 5920, + "is_lead": false + }, + { + "name": "Martin Carton", + "github": "mcarton", + "github_id": 3751788, + "is_lead": false + }, + { + "name": "Vikrant Chaudhary", + "github": "nasa42", + "github_id": 233999, + "is_lead": false + }, + { + "name": "Paul Daniel Faria", + "github": "Nashenas88", + "github_id": 1673130, + "is_lead": false + }, + { + "name": "Nathan Whitaker", + "github": "nathanwhit", + "github_id": 17734409, + "is_lead": false + }, + { + "name": "Nicolette Verlinden", + "github": "niconii", + "github_id": 10183419, + "is_lead": false + }, + { + "name": "Oliver Middleton", + "github": "ollie27", + "github_id": 7189418, + "is_lead": false + }, + { + "name": "Onur Aslan", + "github": "onur", + "github_id": 345828, + "is_lead": false + }, + { + "name": "Paolo Teti", + "github": "paoloteti", + "github_id": 35451649, + "is_lead": false + }, + { + "name": "James Duley", + "github": "parched", + "github_id": 5975405, + "is_lead": false + }, + { + "name": "Patrick Walton", + "github": "pcwalton", + "github_id": 157897, + "is_lead": false + }, + { + "name": "Jeremiah Peschka", + "github": "peschkaj", + "github_id": 71570, + "is_lead": false + }, + { + "name": "Vadzim Dambrouski", + "github": "pftbest", + "github_id": 1573340, + "is_lead": false + }, + { + "name": "pierwill", + "github": "pierwill", + "github_id": 19642016, + "is_lead": false + }, + { + "name": "Douglas Campos", + "github": "qmx", + "github_id": 66734, + "is_lead": false + }, + { + "name": "QuietMisdreavus", + "github": "QuietMisdreavus", + "github_id": 5217170, + "is_lead": false + }, + { + "name": "Russell Johnston", + "github": "rpjohnst", + "github_id": 161677, + "is_lead": false + }, + { + "name": "Stéphane Campinas", + "github": "scampi", + "github_id": 795879, + "is_lead": false + }, + { + "name": "Hideki Sekine", + "github": "sekineh", + "github_id": 3956266, + "is_lead": false + }, + { + "name": "Steven Fackler", + "github": "sfackler", + "github_id": 1455697, + "is_lead": false + }, + { + "name": "Scott Olson", + "github": "solson", + "github_id": 26806, + "is_lead": false + }, + { + "name": "Steve Klabnik", + "github": "steveklabnik", + "github_id": 27786, + "is_lead": false + }, + { + "name": "Stuart Small", + "github": "stusmall", + "github_id": 1697444, + "is_lead": false + }, + { + "name": "Tim Neumann", + "github": "TimNN", + "github_id": 1178249, + "is_lead": false + }, + { + "name": "Togi Sergey", + "github": "togiberlin", + "github_id": 13764830, + "is_lead": false + }, + { + "name": "Tom Prince", + "github": "tomprince", + "github_id": 283816, + "is_lead": false + }, + { + "name": "Seiichi Uchida", + "github": "topecongiro", + "github_id": 21980157, + "is_lead": false + }, + { + "name": "vaishali Thakkar", + "github": "v-thakkar", + "github_id": 7105009, + "is_lead": false + }, + { + "name": "valgrimm", + "github": "valgrimm", + "github_id": 56933147, + "is_lead": false + }, + { + "name": "whitequark", + "github": "whitequark", + "github_id": 54771, + "is_lead": false + }, + { + "name": "Without Boats", + "github": "withoutboats", + "github_id": 9063376, + "is_lead": false + }, + { + "name": "Ioannis Valasakis", + "github": "wizofe", + "github_id": 22352218, + "is_lead": false + }, + { + "name": "Yehuda Katz", + "github": "wycats", + "github_id": 4, + "is_lead": false + }, + { + "name": "Joel Wejdenstål", + "github": "xacrimon", + "github_id": 21025159, + "is_lead": false + }, + { + "name": "Erin Power", + "github": "XAMPPRocky", + "github_id": 4464295, + "is_lead": false + }, + { + "name": "Zack M. Davis", + "github": "zackmdavis", + "github_id": 1076988, + "is_lead": false + }, + { + "name": "Zahari Dichev", + "github": "zaharidichev", + "github_id": 4391506, + "is_lead": false + }, + { + "name": "Zeeshan Ali", + "github": "zeenix", + "github_id": 2027, + "is_lead": false + }, + { + "name": "Zoxc", + "github": "Zoxc", + "github_id": 25784, + "is_lead": false + } + ], + "alumni": [], + "github": null, + "website_data": { + "name": "Rust team alumni", + "description": "Enjoying a leisurely retirement", + "page": "alumni", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": -1000 + }, + "discord": [] + }, + "android": { + "name": "android", + "kind": "marker_team", + "subteam_of": null, + "members": [ + { + "name": "Chris Wailes", + "github": "chriswailes", + "github_id": 530751, + "is_lead": false + }, + { + "name": "Matthew Maurer", + "github": "maurer", + "github_id": 136037, + "is_lead": false + }, + { + "name": "Martin Geisler", + "github": "mgeisler", + "github_id": 89623, + "is_lead": false + }, + { + "name": "Stephen Hines", + "github": "stephenhines", + "github_id": 17790020, + "is_lead": false + } + ], + "alumni": [], + "github": null, + "website_data": null, + "discord": [] + }, + "arm": { + "name": "arm", + "kind": "marker_team", + "subteam_of": null, + "members": [ + { + "name": "Adam Gemmell", + "github": "adamgemmell", + "github_id": 3757567, + "is_lead": false + }, + { + "name": "Hugues de Valon", + "github": "hug-dev", + "github_id": 29229160, + "is_lead": false + }, + { + "name": "Jacob Bramley", + "github": "jacobbramley", + "github_id": 5206553, + "is_lead": false + }, + { + "name": "Jamie Cunliffe", + "github": "JamieCunliffe", + "github_id": 29557119, + "is_lead": false + }, + { + "name": "João Paulo Carreiro", + "github": "joaopaulocarreiro", + "github_id": 44179172, + "is_lead": false + }, + { + "name": "Robin Randhawa", + "github": "raw-bin", + "github_id": 705890, + "is_lead": false + }, + { + "name": "Stam Markianos-Wright", + "github": "Stammark", + "github_id": 30555766, + "is_lead": false + } + ], + "alumni": [], + "github": null, + "website_data": null, + "discord": [] + }, + "bootstrap": { + "name": "bootstrap", + "kind": "team", + "subteam_of": "infra", + "members": [ + { + "name": "Joshua Nelson", + "github": "jyn514", + "github_id": 23638587, + "is_lead": true + }, + { + "name": "Mark Rousskov", + "github": "Mark-Simulacrum", + "github_id": 5047365, + "is_lead": true + }, + { + "name": "Albert Larsan", + "github": "albertlarsan68", + "github_id": 74931857, + "is_lead": false + }, + { + "name": "Onur Özkan", + "github": "ozkanonur", + "github_id": 39852038, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "bootstrap", + "members": [ + 5047365, + 74931857, + 23638587, + 39852038 + ] + } + ] + }, + "website_data": { + "name": "Bootstrap team", + "description": "Maintaining and improving the build system for rust-lang/rust", + "page": "bootstrap", + "email": "bootstrap@rust-lang.org", + "repo": null, + "discord": null, + "zulip_stream": "t-infra/bootstrap", + "weight": 0 + }, + "discord": [] + }, + "cargo": { + "name": "cargo", + "kind": "team", + "subteam_of": "devtools", + "members": [ + { + "name": "Eric Huss", + "github": "ehuss", + "github_id": 43198, + "is_lead": true + }, + { + "name": "Jacob Finkelman", + "github": "Eh2406", + "github_id": 3709504, + "is_lead": false + }, + { + "name": "Ed Page", + "github": "epage", + "github_id": 60961, + "is_lead": false + }, + { + "name": "Josh Triplett", + "github": "joshtriplett", + "github_id": 162737, + "is_lead": false + }, + { + "name": "Weihang Lo", + "github": "weihanglo", + "github_id": 14314532, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Alex Crichton", + "github": "alexcrichton", + "github_id": 64996, + "is_lead": false + }, + { + "name": "Dale Wijnand", + "github": "dwijnand", + "github_id": 344610, + "is_lead": false + }, + { + "name": "Nick Cameron", + "github": "nrc", + "github_id": 762626, + "is_lead": false + }, + { + "name": "Without Boats", + "github": "withoutboats", + "github_id": 9063376, + "is_lead": false + }, + { + "name": "Yehuda Katz", + "github": "wycats", + "github_id": 4, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "cargo", + "members": [ + 3709504, + 43198, + 60961, + 162737, + 14314532 + ] + }, + { + "org": "rust-lang-nursery", + "name": "cargo", + "members": [ + 3709504, + 43198, + 60961, + 162737, + 14314532 + ] + } + ] + }, + "website_data": { + "name": "Cargo team", + "description": "Designing and implementing the official Rust package manager, Cargo", + "page": "cargo", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": "t-cargo", + "weight": 0 + }, + "discord": [] + }, + "clippy": { + "name": "clippy", + "kind": "team", + "subteam_of": "devtools", + "members": [ + { + "name": "Philipp Krones", + "github": "flip1995", + "github_id": 9744647, + "is_lead": true + }, + { + "name": "Manish Goregaokar", + "github": "Manishearth", + "github_id": 1617736, + "is_lead": true + }, + { + "name": "Alex Macleod", + "github": "Alexendoo", + "github_id": 1830331, + "is_lead": false + }, + { + "name": "Cameron Steffen", + "github": "camsteffen", + "github_id": 5565418, + "is_lead": false + }, + { + "name": "dswij", + "github": "dswij", + "github_id": 44697459, + "is_lead": false + }, + { + "name": "Takayuki Nakata", + "github": "giraffate", + "github_id": 17407489, + "is_lead": false + }, + { + "name": "Jason Newcomb", + "github": "Jarcho", + "github_id": 7761774, + "is_lead": false + }, + { + "name": "Andre Bogus", + "github": "llogiq", + "github_id": 4200835, + "is_lead": false + }, + { + "name": "Matthias Krüger", + "github": "matthiaskrgr", + "github_id": 476013, + "is_lead": false + }, + { + "name": "Fridtjof Stoldt", + "github": "xFrednet", + "github_id": 17087237, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Eduardo Broto", + "github": "ebroto", + "github_id": 816908, + "is_lead": false + }, + { + "name": "Pascal Hertleif", + "github": "killercup", + "github_id": 20063, + "is_lead": false + }, + { + "name": "Martin Carton", + "github": "mcarton", + "github_id": 3751788, + "is_lead": false + }, + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": false + }, + { + "name": "Philipp Hansch", + "github": "phansch", + "github_id": 2042399, + "is_lead": false + }, + { + "name": "Jane Lusby", + "github": "yaahc", + "github_id": 1993852, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "clippy", + "members": [ + 1830331, + 7761774, + 1617736, + 5565418, + 44697459, + 9744647, + 17407489, + 4200835, + 476013, + 17087237 + ] + } + ] + }, + "website_data": { + "name": "Clippy team", + "description": "Designing and implementing the Clippy linter", + "page": "clippy", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": "clippy", + "weight": 0 + }, + "discord": [] + }, + "cloud-compute": { + "name": "cloud-compute", + "kind": "marker_team", + "subteam_of": null, + "members": [ + { + "name": "Albert Larsan", + "github": "albertlarsan68", + "github_id": 74931857, + "is_lead": false + }, + { + "name": " Aïssata Maiga", + "github": "Dajamante", + "github_id": 40670675, + "is_lead": false + }, + { + "name": "Jacob Pratt", + "github": "jhpratt", + "github_id": 3161395, + "is_lead": false + }, + { + "name": "Joel Marcey", + "github": "JoelMarcey", + "github_id": 3757713, + "is_lead": false + }, + { + "name": "Julian Knodt", + "github": "JulianKnodt", + "github_id": 7675847, + "is_lead": false + }, + { + "name": "Nell Shamrell-Harrington", + "github": "nellshamrell", + "github_id": 813007, + "is_lead": false + }, + { + "name": "Oguz", + "github": "ouz-a", + "github_id": 90461915, + "is_lead": false + }, + { + "name": "Vincenzo Palazzo", + "github": "vincenzopalazzo", + "github_id": 17150045, + "is_lead": false + }, + { + "name": "Waffle Maybe", + "github": "WaffleLapkin", + "github_id": 38225716, + "is_lead": false + }, + { + "name": "Jane Lusby", + "github": "yaahc", + "github_id": 1993852, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "cloud-compute-team", + "members": [ + 40670675, + 3757713, + 7675847, + 38225716, + 74931857, + 3161395, + 813007, + 90461915, + 17150045, + 1993852 + ] + } + ] + }, + "website_data": null, + "discord": [] + }, + "community": { + "name": "community", + "kind": "team", + "subteam_of": null, + "members": [ + { + "name": "Jan-Erik Rediger", + "github": "badboy", + "github_id": 2129, + "is_lead": false + }, + { + "name": "Yuki Okushi", + "github": "JohnTitor", + "github_id": 25030997, + "is_lead": false + }, + { + "name": "Manish Goregaokar", + "github": "Manishearth", + "github_id": 1617736, + "is_lead": false + }, + { + "name": "Nell Shamrell-Harrington", + "github": "nellshamrell", + "github_id": 813007, + "is_lead": false + }, + { + "name": "Sebastián Magrí", + "github": "sebasmagri", + "github_id": 11137, + "is_lead": false + }, + { + "name": "Olive Gould", + "github": "technetos", + "github_id": 10949810, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Ashley Williams", + "github": "ashleygwilliams", + "github_id": 1163554, + "is_lead": false + }, + { + "name": "Liv", + "github": "shadows-withal", + "github_id": 6445316, + "is_lead": false + }, + { + "name": "Florian Gilcher", + "github": "skade", + "github_id": 47542, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "community", + "members": [ + 25030997, + 1617736, + 2129, + 813007, + 11137, + 10949810 + ] + } + ] + }, + "website_data": null, + "discord": [ + { + "name": "community-team", + "members": [ + 443810603417731092, + 244302461718757376, + 347670185806659585, + 278623213448331265, + 818556851112902657, + 362122860673892353 + ], + "color": "#c27c0e" + } + ] + }, + "community-content": { + "name": "community-content", + "kind": "team", + "subteam_of": "community", + "members": [ + { + "name": "Aditya Arora", + "github": "adityac8", + "github_id": 19192257, + "is_lead": false + }, + { + "name": "Nell Shamrell-Harrington", + "github": "nellshamrell", + "github_id": 813007, + "is_lead": false + }, + { + "name": "Wesley Moore", + "github": "wezm", + "github_id": 21787, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Vikrant Chaudhary", + "github": "nasa42", + "github_id": 233999, + "is_lead": false + }, + { + "name": "Florian Gilcher", + "github": "skade", + "github_id": 47542, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "community-content", + "members": [ + 19192257, + 813007, + 21787 + ] + } + ] + }, + "website_data": { + "name": "Content team", + "description": "Collecting and developing community content", + "page": "community-content", + "email": null, + "repo": "https://github.com/rust-community/content-team", + "discord": { + "channel": "#content-team", + "url": "https://discord.gg/b7a22kw" + }, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "community-ctcft": { + "name": "community-ctcft", + "kind": "team", + "subteam_of": "community", + "members": [ + { + "name": "Forest Anderson", + "github": "AngelOnFira", + "github_id": 14791619, + "is_lead": true + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": true + }, + { + "name": "Olive Gould", + "github": "technetos", + "github_id": 10949810, + "is_lead": false + }, + { + "name": "Jane Lusby", + "github": "yaahc", + "github_id": 1993852, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "community-ctcft", + "members": [ + 14791619, + 155238, + 10949810, + 1993852 + ] + } + ] + }, + "website_data": null, + "discord": [] + }, + "community-events": { + "name": "community-events", + "kind": "team", + "subteam_of": "community", + "members": [ + { + "name": "Jan-Erik Rediger", + "github": "badboy", + "github_id": 2129, + "is_lead": false + }, + { + "name": "Claus Matzinger", + "github": "celaus", + "github_id": 713346, + "is_lead": false + }, + { + "name": "István Szmozsánszky", + "github": "flaki", + "github_id": 2089432, + "is_lead": false + }, + { + "name": "Yuki Okushi", + "github": "JohnTitor", + "github_id": 25030997, + "is_lead": false + }, + { + "name": "Manish Goregaokar", + "github": "Manishearth", + "github_id": 1617736, + "is_lead": false + }, + { + "name": "Matt Gathu", + "github": "mattgathu", + "github_id": 1155192, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Florian Gilcher", + "github": "skade", + "github_id": 47542, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "community-events", + "members": [ + 25030997, + 1617736, + 2129, + 713346, + 2089432, + 1155192 + ] + } + ] + }, + "website_data": { + "name": "Events team", + "description": "Supporting and organizing community events", + "page": "community-events", + "email": null, + "repo": "https://github.com/rust-community/events-team", + "discord": { + "channel": "#events", + "url": "https://discord.gg/cj5HMXA" + }, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "community-localization": { + "name": "community-localization", + "kind": "team", + "subteam_of": "community", + "members": [ + { + "name": "Manish Goregaokar", + "github": "Manishearth", + "github_id": 1617736, + "is_lead": true + }, + { + "name": "Mahmut Bulut", + "github": "vertexclique", + "github_id": 578559, + "is_lead": true + }, + { + "name": "Yuki Okushi", + "github": "JohnTitor", + "github_id": 25030997, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Erin Power", + "github": "XAMPPRocky", + "github_id": 4464295, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "community-localization", + "members": [ + 25030997, + 1617736, + 578559 + ] + } + ] + }, + "website_data": { + "name": "Localization team", + "description": "Working on localization of compiler, documentation and websites", + "page": "community-localization", + "email": null, + "repo": "https://github.com/rust-lang/community-localization", + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "community-rustbridge": { + "name": "community-rustbridge", + "kind": "team", + "subteam_of": "community", + "members": [ + { + "name": "Liv", + "github": "shadows-withal", + "github_id": 6445316, + "is_lead": true + }, + { + "name": "Arshia Mufti", + "github": "arshiamufti", + "github_id": 15066212, + "is_lead": false + }, + { + "name": "Matt Gathu", + "github": "mattgathu", + "github_id": 1155192, + "is_lead": false + }, + { + "name": "Sebastián Magrí", + "github": "sebasmagri", + "github_id": 11137, + "is_lead": false + }, + { + "name": "Katharina Fey", + "github": "spacekookie", + "github_id": 7669898, + "is_lead": false + }, + { + "name": "Olive Gould", + "github": "technetos", + "github_id": 10949810, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Ashley Williams", + "github": "ashleygwilliams", + "github_id": 1163554, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "community-rustbridge", + "members": [ + 15066212, + 1155192, + 11137, + 6445316, + 7669898, + 10949810 + ] + } + ] + }, + "website_data": { + "name": "RustBridge team", + "description": "Helping to bring underrepresented groups into Rust", + "page": "community-rustbridge", + "email": null, + "repo": "https://github.com/rustbridge/team", + "discord": { + "channel": "#rustbridge", + "url": "https://discord.gg/cj5HMXA" + }, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "community-survey": { + "name": "community-survey", + "kind": "team", + "subteam_of": "community", + "members": [ + { + "name": "Ryan Levick", + "github": "rylev", + "github_id": 1327285, + "is_lead": true + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": false + }, + { + "name": "Nick Cameron", + "github": "nrc", + "github_id": 762626, + "is_lead": false + }, + { + "name": "Jane Lusby", + "github": "yaahc", + "github_id": 1993852, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "community-survey", + "members": [ + 155238, + 762626, + 1327285, + 1993852 + ] + } + ] + }, + "website_data": { + "name": "Survey team", + "description": "Running, analysing, and presenting the community survey", + "page": "community-survey", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "compiler": { + "name": "compiler", + "kind": "team", + "subteam_of": null, + "members": [ + { + "name": "Felix Klock", + "github": "pnkfelix", + "github_id": 173127, + "is_lead": true + }, + { + "name": "Wesley Wiser", + "github": "wesleywiser", + "github_id": 831192, + "is_lead": true + }, + { + "name": "Aaron Hill", + "github": "Aaron1011", + "github_id": 1408859, + "is_lead": false + }, + { + "name": "Camille Gillot", + "github": "cjgillot", + "github_id": 1822483, + "is_lead": false + }, + { + "name": "David Wood", + "github": "davidtwco", + "github_id": 1295100, + "is_lead": false + }, + { + "name": "Eduard-Mihai Burtescu", + "github": "eddyb", + "github_id": 77424, + "is_lead": false + }, + { + "name": "Esteban Kuber", + "github": "estebank", + "github_id": 1606434, + "is_lead": false + }, + { + "name": "lcnr", + "github": "lcnr", + "github_id": 29864074, + "is_lead": false + }, + { + "name": "Matthew Jasper", + "github": "matthewjasper", + "github_id": 20113453, + "is_lead": false + }, + { + "name": "Michael Woerister", + "github": "michaelwoerister", + "github_id": 1825894, + "is_lead": false + }, + { + "name": "Simonas Kazlauskas", + "github": "nagisa", + "github_id": 679122, + "is_lead": false + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": false + }, + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": false + }, + { + "name": "Vadim Petrochenkov", + "github": "petrochenkov", + "github_id": 5751617, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Taylor Cramer", + "github": "cramertj", + "github_id": 5963049, + "is_lead": false + }, + { + "name": "Björn Steinbrink", + "github": "dotdash", + "github_id": 230962, + "is_lead": false + }, + { + "name": "Nick Cameron", + "github": "nrc", + "github_id": 762626, + "is_lead": false + }, + { + "name": "varkor", + "github": "varkor", + "github_id": 3943692, + "is_lead": false + }, + { + "name": "Zoxc", + "github": "Zoxc", + "github_id": 25784, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "compiler", + "members": [ + 1408859, + 1822483, + 1295100, + 77424, + 1606434, + 29864074, + 20113453, + 1825894, + 679122, + 155238, + 332036, + 5751617, + 173127, + 831192 + ] + }, + { + "org": "rust-lang-nursery", + "name": "compiler", + "members": [ + 1408859, + 1822483, + 1295100, + 77424, + 1606434, + 29864074, + 20113453, + 1825894, + 679122, + 155238, + 332036, + 5751617, + 173127, + 831192 + ] + } + ] + }, + "website_data": { + "name": "Compiler team", + "description": "Developing and managing compiler internals and optimizations", + "page": "compiler", + "email": null, + "repo": "http://github.com/rust-lang/compiler-team", + "discord": null, + "zulip_stream": "t-compiler", + "weight": 0 + }, + "discord": [] + }, + "compiler-contributors": { + "name": "compiler-contributors", + "kind": "team", + "subteam_of": "compiler", + "members": [ + { + "name": "bjorn3", + "github": "bjorn3", + "github_id": 17426603, + "is_lead": false + }, + { + "name": "Boxy", + "github": "BoxyUwU", + "github_id": 21149742, + "is_lead": false + }, + { + "name": "Michael Goulet", + "github": "compiler-errors", + "github_id": 3674314, + "is_lead": false + }, + { + "name": "Josh Stone", + "github": "cuviper", + "github_id": 36186, + "is_lead": false + }, + { + "name": "Dylan MacKenzie", + "github": "ecstatic-morse", + "github_id": 29463364, + "is_lead": false + }, + { + "name": "Eric Holk", + "github": "eholk", + "github_id": 105766, + "is_lead": false + }, + { + "name": "Deadbeef", + "github": "fee1-dead", + "github_id": 43851243, + "is_lead": false + }, + { + "name": "Florian Diebold", + "github": "flodiebold", + "github_id": 906069, + "is_lead": false + }, + { + "name": "Jack Huey", + "github": "jackh726", + "github_id": 31162821, + "is_lead": false + }, + { + "name": "Jonas Schievink", + "github": "jonas-schievink", + "github_id": 1786438, + "is_lead": false + }, + { + "name": "Rémy Rakic", + "github": "lqd", + "github_id": 247183, + "is_lead": false + }, + { + "name": "Mark Rousskov", + "github": "Mark-Simulacrum", + "github_id": 5047365, + "is_lead": false + }, + { + "name": "Aleksey Kladov", + "github": "matklad", + "github_id": 1711539, + "is_lead": false + }, + { + "name": "Nadrieril", + "github": "Nadrieril", + "github_id": 6783654, + "is_lead": false + }, + { + "name": "Nikita Popov", + "github": "nikic", + "github_id": 216080, + "is_lead": false + }, + { + "name": "nils", + "github": "Nilstrieb", + "github_id": 48135649, + "is_lead": false + }, + { + "name": "Nicholas Nethercote", + "github": "nnethercote", + "github_id": 1940286, + "is_lead": false + }, + { + "name": "Ralf Jung", + "github": "RalfJung", + "github_id": 330628, + "is_lead": false + }, + { + "name": "Alexandre Martin", + "github": "scalexm", + "github_id": 1173131, + "is_lead": false + }, + { + "name": "Santiago Pastorino", + "github": "spastorino", + "github_id": 52642, + "is_lead": false + }, + { + "name": "Takayuki Maeda", + "github": "TaKO8Ki", + "github_id": 41065217, + "is_lead": false + }, + { + "name": "The 8472", + "github": "the8472", + "github_id": 1065730, + "is_lead": false + }, + { + "name": "Tyler Mandry", + "github": "tmandry", + "github_id": 2280544, + "is_lead": false + }, + { + "name": "tmiasko", + "github": "tmiasko", + "github_id": 51362316, + "is_lead": false + }, + { + "name": "varkor", + "github": "varkor", + "github_id": 3943692, + "is_lead": false + }, + { + "name": "Waffle Maybe", + "github": "WaffleLapkin", + "github_id": 38225716, + "is_lead": false + }, + { + "name": "Igor Matuszewski", + "github": "Xanewok", + "github_id": 3093213, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Mazdak Farrokhzad", + "github": "Centril", + "github_id": 855702, + "is_lead": false + }, + { + "name": "Léo Lanteri Thauvin", + "github": "LeSeulArtichaut", + "github_id": 38361244, + "is_lead": false + }, + { + "name": "Zack M. Davis", + "github": "zackmdavis", + "github_id": 1076988, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "compiler-contributors", + "members": [ + 1408859, + 21149742, + 5047365, + 6783654, + 48135649, + 330628, + 41065217, + 38225716, + 3093213, + 17426603, + 1822483, + 3674314, + 36186, + 1295100, + 29463364, + 77424, + 105766, + 1606434, + 43851243, + 906069, + 31162821, + 1786438, + 29864074, + 247183, + 1711539, + 20113453, + 1825894, + 679122, + 216080, + 155238, + 1940286, + 332036, + 5751617, + 173127, + 1173131, + 52642, + 1065730, + 2280544, + 51362316, + 3943692, + 831192 + ] + }, + { + "org": "rust-lang-nursery", + "name": "compiler-contributors", + "members": [ + 1408859, + 21149742, + 5047365, + 6783654, + 48135649, + 330628, + 41065217, + 38225716, + 3093213, + 17426603, + 1822483, + 3674314, + 36186, + 1295100, + 29463364, + 77424, + 105766, + 1606434, + 43851243, + 906069, + 31162821, + 1786438, + 29864074, + 247183, + 1711539, + 20113453, + 1825894, + 679122, + 216080, + 155238, + 1940286, + 332036, + 5751617, + 173127, + 1173131, + 52642, + 1065730, + 2280544, + 51362316, + 3943692, + 831192 + ] + } + ] + }, + "website_data": { + "name": "Compiler team contributors", + "description": "Contributing to the Rust compiler on a regular basis", + "page": "compiler-contributors", + "email": null, + "repo": "http://github.com/rust-lang/compiler-team", + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "core": { + "name": "core", + "kind": "team", + "subteam_of": null, + "members": [ + { + "name": "Jan-Erik Rediger", + "github": "badboy", + "github_id": 2129, + "is_lead": false + }, + { + "name": "JT", + "github": "jntrnr", + "github_id": 547158, + "is_lead": false + }, + { + "name": "Mark Rousskov", + "github": "Mark-Simulacrum", + "github_id": 5047365, + "is_lead": false + }, + { + "name": "Ryan Levick", + "github": "rylev", + "github_id": 1327285, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Aidan Hobson Sayers", + "github": "aidanhs", + "github_id": 1050652, + "is_lead": false + }, + { + "name": "Ashley Williams", + "github": "ashleygwilliams", + "github_id": 1163554, + "is_lead": false + }, + { + "name": "Carol Nichols", + "github": "carols10cents", + "github_id": 193874, + "is_lead": false + }, + { + "name": "Manish Goregaokar", + "github": "Manishearth", + "github_id": 1617736, + "is_lead": false + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": false + }, + { + "name": "Nick Cameron", + "github": "nrc", + "github_id": 762626, + "is_lead": false + }, + { + "name": "Pietro Albini", + "github": "pietroalbini", + "github_id": 2299951, + "is_lead": false + }, + { + "name": "Florian Gilcher", + "github": "skade", + "github_id": 47542, + "is_lead": false + }, + { + "name": "Steve Klabnik", + "github": "steveklabnik", + "github_id": 27786, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "core", + "members": [ + 5047365, + 2129, + 547158, + 1327285 + ] + }, + { + "org": "rust-lang-nursery", + "name": "core", + "members": [ + 5047365, + 2129, + 547158, + 1327285 + ] + } + ] + }, + "website_data": { + "name": "Core team", + "description": "Managing the overall direction of Rust, subteam leadership, and any cross-cutting issues", + "page": "core", + "email": "core@rust-lang.org", + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 1000 + }, + "discord": [ + { + "name": "core-team", + "members": [ + 278605906332221441, + 401012249436749834, + 442403469580566528, + 347670185806659585 + ], + "color": "#3498db" + } + ] + }, + "crate-maintainers": { + "name": "crate-maintainers", + "kind": "team", + "subteam_of": "libs", + "members": [ + { + "name": "Amanieu d'Antras", + "github": "Amanieu", + "github_id": 278509, + "is_lead": false + }, + { + "name": "Chris Denton", + "github": "ChrisDenton", + "github_id": 4459874, + "is_lead": false + }, + { + "name": "Yuki Okushi", + "github": "JohnTitor", + "github_id": 25030997, + "is_lead": false + }, + { + "name": "Josh Triplett", + "github": "joshtriplett", + "github_id": 162737, + "is_lead": false + }, + { + "name": "Ashley Mannix", + "github": "KodrAus", + "github_id": 6721458, + "is_lead": false + }, + { + "name": "The 8472", + "github": "the8472", + "github_id": 1065730, + "is_lead": false + }, + { + "name": "Thom Chiovoloni", + "github": "thomcc", + "github_id": 860665, + "is_lead": false + }, + { + "name": "Jubilee", + "github": "workingjubilee", + "github_id": 46493976, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "crate-maintainers", + "members": [ + 278509, + 4459874, + 25030997, + 6721458, + 162737, + 1065730, + 860665, + 46493976 + ] + } + ] + }, + "website_data": { + "name": "Crate maintainers", + "description": "Maintaining official rust-lang crates such as log, libc, cc, and more.", + "page": "crate-maintainers", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": "t-libs/crates", + "weight": -200 + }, + "discord": [] + }, + "crates-io": { + "name": "crates-io", + "kind": "team", + "subteam_of": null, + "members": [ + { + "name": "Justin Geibel", + "github": "jtgeibel", + "github_id": 22186, + "is_lead": true + }, + { + "name": "Tobias Bieniek", + "github": "Turbo87", + "github_id": 141300, + "is_lead": true + }, + { + "name": "Carol Nichols", + "github": "carols10cents", + "github_id": 193874, + "is_lead": false + }, + { + "name": "Yuki Okushi", + "github": "JohnTitor", + "github_id": 25030997, + "is_lead": false + }, + { + "name": "Ricardo Mendes", + "github": "locks", + "github_id": 32344, + "is_lead": false + }, + { + "name": "Florian Pichler", + "github": "pichfl", + "github_id": 194641, + "is_lead": false + }, + { + "name": "Sven Marnach", + "github": "smarnach", + "github_id": 249196, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Ashley Williams", + "github": "ashleygwilliams", + "github_id": 1163554, + "is_lead": false + }, + { + "name": "二手掉包工程师", + "github": "hi-rustin", + "github_id": 29879298, + "is_lead": false + }, + { + "name": "Tatsuyuki Ishi", + "github": "ishitatsuyuki", + "github_id": 12389383, + "is_lead": false + }, + { + "name": "Josh Triplett", + "github": "joshtriplett", + "github_id": 162737, + "is_lead": false + }, + { + "name": "Nell Shamrell-Harrington", + "github": "nellshamrell", + "github_id": 813007, + "is_lead": false + }, + { + "name": "Pietro Albini", + "github": "pietroalbini", + "github_id": 2299951, + "is_lead": false + }, + { + "name": "Sage Griffin", + "github": "sgrif", + "github_id": 1529387, + "is_lead": false + }, + { + "name": "Steve Klabnik", + "github": "steveklabnik", + "github_id": 27786, + "is_lead": false + }, + { + "name": "Without Boats", + "github": "withoutboats", + "github_id": 9063376, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "conduit-rust", + "name": "crates-io", + "members": [ + 25030997, + 141300, + 193874, + 22186, + 32344, + 194641, + 249196 + ] + }, + { + "org": "rust-lang", + "name": "crates-io", + "members": [ + 25030997, + 141300, + 193874, + 22186, + 32344, + 194641, + 249196 + ] + } + ] + }, + "website_data": { + "name": "Crates.io team", + "description": "Managing operations, development, and official policies for crates.io", + "page": "crates-io", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": "t-crates-io", + "weight": 0 + }, + "discord": [] + }, + "crates-io-on-call": { + "name": "crates-io-on-call", + "kind": "marker_team", + "subteam_of": null, + "members": [ + { + "name": "Jonas Schievink", + "github": "jonas-schievink", + "github_id": 1786438, + "is_lead": false + }, + { + "name": "Sebastian Ziebell", + "github": "justahero", + "github_id": 1305185, + "is_lead": false + }, + { + "name": "Андрей Листочкин (Andrei Listochkin)", + "github": "listochkin", + "github_id": 405222, + "is_lead": false + }, + { + "name": "Pietro Albini", + "github": "pietroalbini", + "github_id": 2299951, + "is_lead": false + }, + { + "name": "Florian Gilcher", + "github": "skade", + "github_id": 47542, + "is_lead": false + }, + { + "name": "Felix Gilcher", + "github": "Xylakant", + "github_id": 337823, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "crates-io-on-call", + "members": [ + 337823, + 1786438, + 1305185, + 405222, + 2299951, + 47542 + ] + } + ] + }, + "website_data": null, + "discord": [] + }, + "devtools": { + "name": "devtools", + "kind": "team", + "subteam_of": null, + "members": [ + { + "name": "Manish Goregaokar", + "github": "Manishearth", + "github_id": 1617736, + "is_lead": true + }, + { + "name": "Eric Huss", + "github": "ehuss", + "github_id": 43198, + "is_lead": false + }, + { + "name": "Nick Fitzgerald", + "github": "fitzgen", + "github_id": 74571, + "is_lead": false + }, + { + "name": "Guillaume Gomez", + "github": "GuillaumeGomez", + "github_id": 3050060, + "is_lead": false + }, + { + "name": "Daniel Silverstone", + "github": "kinnison", + "github_id": 1469421, + "is_lead": false + }, + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": false + }, + { + "name": "Igor Matuszewski", + "github": "Xanewok", + "github_id": 3093213, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Pascal Hertleif", + "github": "killercup", + "github_id": 20063, + "is_lead": false + }, + { + "name": "Nick Cameron", + "github": "nrc", + "github_id": 762626, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-dev-tools", + "name": "devtools", + "members": [ + 3050060, + 1617736, + 3093213, + 43198, + 74571, + 1469421, + 332036 + ] + }, + { + "org": "rust-lang", + "name": "devtools", + "members": [ + 3050060, + 1617736, + 3093213, + 43198, + 74571, + 1469421, + 332036 + ] + } + ] + }, + "website_data": { + "name": "Dev tools team", + "description": "Contributing to and creating the Rust development tools", + "page": "dev-tools", + "email": "tools@rust-lang.org", + "repo": "https://github.com/rust-dev-tools/dev-tools-team", + "discord": null, + "zulip_stream": "t-devtools", + "weight": 0 + }, + "discord": [] + }, + "docs-rs": { + "name": "docs-rs", + "kind": "team", + "subteam_of": "devtools", + "members": [ + { + "name": "Denis Cornehl", + "github": "syphar", + "github_id": 540890, + "is_lead": true + }, + { + "name": "Sebastian Thiel", + "github": "Byron", + "github_id": 63622, + "is_lead": false + }, + { + "name": "Guillaume Gomez", + "github": "GuillaumeGomez", + "github_id": 3050060, + "is_lead": false + }, + { + "name": "Jacob Hoffman-Andrews", + "github": "jsha", + "github_id": 220205, + "is_lead": false + }, + { + "name": "Joshua Nelson", + "github": "jyn514", + "github_id": 23638587, + "is_lead": false + }, + { + "name": "Wim", + "github": "Nemo157", + "github_id": 81079, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Chase Wilson", + "github": "Kixiron", + "github_id": 25047011, + "is_lead": false + }, + { + "name": "Onur Aslan", + "github": "onur", + "github_id": 345828, + "is_lead": false + }, + { + "name": "Pietro Albini", + "github": "pietroalbini", + "github_id": 2299951, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "docs-rs", + "members": [ + 63622, + 3050060, + 81079, + 220205, + 23638587, + 540890 + ] + }, + { + "org": "rust-lang-nursery", + "name": "docs-rs", + "members": [ + 63622, + 3050060, + 81079, + 220205, + 23638587, + 540890 + ] + } + ] + }, + "website_data": { + "name": "Docs.rs team", + "description": "Docs.rs, the documentation hosting service for crates", + "page": "docs-rs", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": "t-docs-rs", + "weight": 0 + }, + "discord": [] + }, + "emacs": { + "name": "emacs", + "kind": "marker_team", + "subteam_of": null, + "members": [ + { + "name": "brotzeit", + "github": "brotzeit", + "github_id": 25367303, + "is_lead": false + }, + { + "name": "Jim Blandy", + "github": "jimblandy", + "github_id": 751272, + "is_lead": false + }, + { + "name": "Micah Chalmer", + "github": "MicahChalmer", + "github_id": 698400, + "is_lead": false + }, + { + "name": "Felix Klock", + "github": "pnkfelix", + "github_id": 173127, + "is_lead": false + }, + { + "name": "Sibi Prabakaran", + "github": "psibi", + "github_id": 737477, + "is_lead": false + }, + { + "name": "Tom Tromey", + "github": "tromey", + "github_id": 1557670, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "emacs", + "members": [ + 698400, + 25367303, + 751272, + 173127, + 737477, + 1557670 + ] + } + ] + }, + "website_data": null, + "discord": [] + }, + "fuchsia": { + "name": "fuchsia", + "kind": "marker_team", + "subteam_of": null, + "members": [ + { + "name": "andrewpollack", + "github": "andrewpollack", + "github_id": 24868505, + "is_lead": false + }, + { + "name": "Dan Johnson", + "github": "ComputerDruid", + "github_id": 34696, + "is_lead": false + }, + { + "name": "David Koloski", + "github": "djkoloski", + "github_id": 7554649, + "is_lead": false + }, + { + "name": "Joseph Ryan", + "github": "P1n3appl3", + "github_id": 9326885, + "is_lead": false + }, + { + "name": "Tyler Mandry", + "github": "tmandry", + "github_id": 2280544, + "is_lead": false + } + ], + "alumni": [], + "github": null, + "website_data": null, + "discord": [] + }, + "icebreakers-cleanup-crew": { + "name": "icebreakers-cleanup-crew", + "kind": "marker_team", + "subteam_of": null, + "members": [ + { + "name": "Albert Larsan", + "github": "albertlarsan68", + "github_id": 74931857, + "is_lead": false + }, + { + "name": "Amin Arria", + "github": "AminArria", + "github_id": 3791966, + "is_lead": false + }, + { + "name": "hafiz", + "github": "ayazhafiz", + "github_id": 20735482, + "is_lead": false + }, + { + "name": "Noah Lev", + "github": "camelid", + "github_id": 37223377, + "is_lead": false + }, + { + "name": "Chris Simpkins", + "github": "chrissimpkins", + "github_id": 4249591, + "is_lead": false + }, + { + "name": "B YI", + "github": "contrun", + "github_id": 32609395, + "is_lead": false + }, + { + "name": "Michał Siedlaczek", + "github": "elshize", + "github_id": 3026120, + "is_lead": false + }, + { + "name": "Hirokazu Hata", + "github": "h-michael", + "github_id": 4556097, + "is_lead": false + }, + { + "name": "Patrick Haller", + "github": "HallerPatrick", + "github_id": 22773355, + "is_lead": false + }, + { + "name": "Hoàng Đức Hiếu", + "github": "hdhoang", + "github_id": 12537, + "is_lead": false + }, + { + "name": "Marcel", + "github": "hellow554", + "github_id": 921462, + "is_lead": false + }, + { + "name": "Henry Boisdequin", + "github": "henryboisdequin", + "github_id": 65845077, + "is_lead": false + }, + { + "name": "imtsuki", + "github": "imtsuki", + "github_id": 8423594, + "is_lead": false + }, + { + "name": "Ian S. Pringle", + "github": "ispringle", + "github_id": 18722936, + "is_lead": false + }, + { + "name": "James Gill", + "github": "JamesPatrickGill", + "github_id": 44863195, + "is_lead": false + }, + { + "name": "Kan-Ru Chen", + "github": "kanru", + "github_id": 17571, + "is_lead": false + }, + { + "name": "Stefan Kerkmann", + "github": "KarlK90", + "github_id": 13887561, + "is_lead": false + }, + { + "name": "Consoli", + "github": "matheus-consoli", + "github_id": 27595790, + "is_lead": false + }, + { + "name": "mental", + "github": "mental32", + "github_id": 27660514, + "is_lead": false + }, + { + "name": "Nathan McCarty", + "github": "nmccarty", + "github_id": 8325047, + "is_lead": false + }, + { + "name": "Noah Kennedy", + "github": "Noah-Kennedy", + "github_id": 9875622, + "is_lead": false + }, + { + "name": "Peyton Turner", + "github": "PeytonT", + "github_id": 22621596, + "is_lead": false + }, + { + "name": "pierreN", + "github": "pierreN", + "github_id": 946757, + "is_lead": false + }, + { + "name": "Valentin Ricard", + "github": "Redblueflame", + "github_id": 24188356, + "is_lead": false + }, + { + "name": "Robbie Clarken", + "github": "RobbieClarken", + "github_id": 663161, + "is_lead": false + }, + { + "name": "RobertoSnap", + "github": "RobertoSnap", + "github_id": 4772930, + "is_lead": false + }, + { + "name": "Rob Ede", + "github": "robjtede", + "github_id": 3316789, + "is_lead": false + }, + { + "name": "Sarthak Singh", + "github": "SarthakSingh31", + "github_id": 35749450, + "is_lead": false + }, + { + "name": "Shady Khalifa", + "github": "shekohex", + "github_id": 14620076, + "is_lead": false + }, + { + "name": "Shingo Kato", + "github": "sinato", + "github_id": 20817743, + "is_lead": false + }, + { + "name": "Steven Malis", + "github": "smmalis37", + "github_id": 4054472, + "is_lead": false + }, + { + "name": "Frank Steffahn", + "github": "steffahn", + "github_id": 3986214, + "is_lead": false + }, + { + "name": "Stu", + "github": "Stupremee", + "github_id": 39732259, + "is_lead": false + }, + { + "name": "Yohei Tamura", + "github": "tamuhey", + "github_id": 24998666, + "is_lead": false + }, + { + "name": "Steve Loveless", + "github": "turboladen", + "github_id": 142010, + "is_lead": false + }, + { + "name": "Jean SIMARD", + "github": "woshilapin", + "github_id": 2520723, + "is_lead": false + }, + { + "name": "Yerkebulan Tulibergenov", + "github": "yerke", + "github_id": 5137691, + "is_lead": false + } + ], + "alumni": [], + "github": null, + "website_data": null, + "discord": [] + }, + "icebreakers-llvm": { + "name": "icebreakers-llvm", + "kind": "marker_team", + "subteam_of": null, + "members": [ + { + "name": "hafiz", + "github": "ayazhafiz", + "github_id": 20735482, + "is_lead": false + }, + { + "name": "Noah Lev", + "github": "camelid", + "github_id": 37223377, + "is_lead": false + }, + { + "name": "comex", + "github": "comex", + "github_id": 47517, + "is_lead": false + }, + { + "name": "Josh Stone", + "github": "cuviper", + "github_id": 36186, + "is_lead": false + }, + { + "name": "Hoàng Đức Hiếu", + "github": "hdhoang", + "github_id": 12537, + "is_lead": false + }, + { + "name": "Henry Boisdequin", + "github": "henryboisdequin", + "github_id": 65845077, + "is_lead": false + }, + { + "name": "Rutvik Patel", + "github": "heyrutvik", + "github_id": 6268538, + "is_lead": false + }, + { + "name": "Xing GUO", + "github": "higuoxing", + "github_id": 21099318, + "is_lead": false + }, + { + "name": "Youngsuk Kim", + "github": "JOE1994", + "github_id": 10286488, + "is_lead": false + }, + { + "name": "J. Ryan Stinnett", + "github": "jryans", + "github_id": 279572, + "is_lead": false + }, + { + "name": "Luqman Aden", + "github": "luqmana", + "github_id": 287063, + "is_lead": false + }, + { + "name": "Miodrag Milenković", + "github": "mmilenko", + "github_id": 10790773, + "is_lead": false + }, + { + "name": "Simonas Kazlauskas", + "github": "nagisa", + "github_id": 679122, + "is_lead": false + }, + { + "name": "Nikita Popov", + "github": "nikic", + "github_id": 216080, + "is_lead": false + }, + { + "name": "Noah Kennedy", + "github": "Noah-Kennedy", + "github_id": 9875622, + "is_lead": false + }, + { + "name": "Siavosh Zarrasvand", + "github": "SiavoshZarrasvand", + "github_id": 492510, + "is_lead": false + }, + { + "name": "Santiago Pastorino", + "github": "spastorino", + "github_id": 52642, + "is_lead": false + }, + { + "name": "Mahmut Bulut", + "github": "vertexclique", + "github_id": 578559, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Hanna Kruppe", + "github": "hanna-kruppe", + "github_id": 2311707, + "is_lead": false + } + ], + "github": null, + "website_data": null, + "discord": [] + }, + "ides": { + "name": "ides", + "kind": "team", + "subteam_of": "devtools", + "members": [ + { + "name": "Igor Matuszewski", + "github": "Xanewok", + "github_id": 3093213, + "is_lead": true + }, + { + "name": "Alex Butler", + "github": "alexheretic", + "github_id": 2331607, + "is_lead": false + }, + { + "name": "Junfeng Li", + "github": "autozimu", + "github_id": 1453551, + "is_lead": false + }, + { + "name": "Jason Williams", + "github": "jasonwilliams", + "github_id": 936006, + "is_lead": false + }, + { + "name": "Lucas Bullen", + "github": "LucasBullen", + "github_id": 10255066, + "is_lead": false + }, + { + "name": "Aleksey Kladov", + "github": "matklad", + "github_id": 1711539, + "is_lead": false + }, + { + "name": "Vlad Beskrovnyy", + "github": "vlad20012", + "github_id": 3221931, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Nick Cameron", + "github": "nrc", + "github_id": 762626, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "ides", + "members": [ + 10255066, + 3093213, + 2331607, + 1453551, + 936006, + 1711539, + 3221931 + ] + } + ] + }, + "website_data": { + "name": "IDEs and editors team", + "description": "Developing IDEs, editors, and other development tools such as Racer and the RLS", + "page": "ides", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "infra": { + "name": "infra", + "kind": "team", + "subteam_of": null, + "members": [ + { + "name": "Pietro Albini", + "github": "pietroalbini", + "github_id": 2299951, + "is_lead": true + }, + { + "name": "Jan David Nose", + "github": "jdno", + "github_id": 865550, + "is_lead": false + }, + { + "name": "Joshua Nelson", + "github": "jyn514", + "github_id": 23638587, + "is_lead": false + }, + { + "name": "kennytm", + "github": "kennytm", + "github_id": 103023, + "is_lead": false + }, + { + "name": "Mark Rousskov", + "github": "Mark-Simulacrum", + "github_id": 5047365, + "is_lead": false + }, + { + "name": "Ryan Levick", + "github": "rylev", + "github_id": 1327285, + "is_lead": false + }, + { + "name": "Jake Goulding", + "github": "shepmaster", + "github_id": 174509, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Aidan Hobson Sayers", + "github": "aidanhs", + "github_id": 1050652, + "is_lead": false + }, + { + "name": "Ashley Williams", + "github": "ashleygwilliams", + "github_id": 1163554, + "is_lead": false + }, + { + "name": "Nell Shamrell-Harrington", + "github": "nellshamrell", + "github_id": 813007, + "is_lead": false + }, + { + "name": "Sage Griffin", + "github": "sgrif", + "github_id": 1529387, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "bors-rs", + "name": "rust-infra", + "members": [ + 5047365, + 865550, + 23638587, + 103023, + 2299951, + 1327285, + 174509 + ] + }, + { + "org": "rust-lang", + "name": "infra", + "members": [ + 5047365, + 865550, + 23638587, + 103023, + 2299951, + 1327285, + 174509 + ] + }, + { + "org": "rust-lang-ci", + "name": "infra", + "members": [ + 5047365, + 865550, + 23638587, + 103023, + 2299951, + 1327285, + 174509 + ] + }, + { + "org": "rust-lang-nursery", + "name": "infra", + "members": [ + 5047365, + 865550, + 23638587, + 103023, + 2299951, + 1327285, + 174509 + ] + } + ] + }, + "website_data": { + "name": "Infrastructure team", + "description": "Managing the infrastructure supporting the Rust project itself, including CI, releases, bots, and metrics", + "page": "infra", + "email": "infra@rust-lang.org", + "repo": null, + "discord": null, + "zulip_stream": "t-infra", + "weight": 0 + }, + "discord": [ + { + "name": "infra-team", + "members": [ + 296309029947441155, + 382886245069488129, + 568772690438127647, + 453980540824059918, + 442403469580566528, + 953562944472510494, + 401012249436749834 + ], + "color": "#ff5454" + } + ] + }, + "infra-admins": { + "name": "infra-admins", + "kind": "team", + "subteam_of": null, + "members": [ + { + "name": "Jan David Nose", + "github": "jdno", + "github_id": 865550, + "is_lead": false + }, + { + "name": "Mark Rousskov", + "github": "Mark-Simulacrum", + "github_id": 5047365, + "is_lead": false + }, + { + "name": "Pietro Albini", + "github": "pietroalbini", + "github_id": 2299951, + "is_lead": false + } + ], + "alumni": [], + "github": null, + "website_data": null, + "discord": [] + }, + "infra-bors": { + "name": "infra-bors", + "kind": "team", + "subteam_of": "infra", + "members": [ + { + "name": "Mark Rousskov", + "github": "Mark-Simulacrum", + "github_id": 5047365, + "is_lead": true + }, + { + "name": "Jakub Beránek", + "github": "Kobzol", + "github_id": 4539057, + "is_lead": false + }, + { + "name": "Pietro Albini", + "github": "pietroalbini", + "github_id": 2299951, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "infra-bors", + "members": [ + 4539057, + 5047365, + 2299951 + ] + } + ] + }, + "website_data": null, + "discord": [] + }, + "inside-rust-reviewers": { + "name": "inside-rust-reviewers", + "kind": "marker_team", + "subteam_of": null, + "members": [ + { + "name": "Forest Anderson", + "github": "AngelOnFira", + "github_id": 14791619, + "is_lead": false + }, + { + "name": "Andrew Gallant", + "github": "BurntSushi", + "github_id": 456674, + "is_lead": false + }, + { + "name": "Caleb Cartwright", + "github": "calebcartwright", + "github_id": 13042488, + "is_lead": false + }, + { + "name": "Celina V.", + "github": "celinval", + "github_id": 35149715, + "is_lead": false + }, + { + "name": "Charles Lew", + "github": "crlf0710", + "github_id": 451806, + "is_lead": false + }, + { + "name": "Eric Huss", + "github": "ehuss", + "github_id": 43198, + "is_lead": false + }, + { + "name": "Philipp Krones", + "github": "flip1995", + "github_id": 9744647, + "is_lead": false + }, + { + "name": "Guillaume Gomez", + "github": "GuillaumeGomez", + "github_id": 3050060, + "is_lead": false + }, + { + "name": "Jack Huey", + "github": "jackh726", + "github_id": 31162821, + "is_lead": false + }, + { + "name": "Yuki Okushi", + "github": "JohnTitor", + "github_id": 25030997, + "is_lead": false + }, + { + "name": "Josh Triplett", + "github": "joshtriplett", + "github_id": 162737, + "is_lead": false + }, + { + "name": "Justin Geibel", + "github": "jtgeibel", + "github_id": 22186, + "is_lead": false + }, + { + "name": "Joshua Nelson", + "github": "jyn514", + "github_id": 23638587, + "is_lead": false + }, + { + "name": "Daniel Silverstone", + "github": "kinnison", + "github_id": 1469421, + "is_lead": false + }, + { + "name": "lcnr", + "github": "lcnr", + "github_id": 29864074, + "is_lead": false + }, + { + "name": "Mara Bos", + "github": "m-ou-se", + "github_id": 783247, + "is_lead": false + }, + { + "name": "Manish Goregaokar", + "github": "Manishearth", + "github_id": 1617736, + "is_lead": false + }, + { + "name": "Mark Rousskov", + "github": "Mark-Simulacrum", + "github_id": 5047365, + "is_lead": false + }, + { + "name": "Michael Woerister", + "github": "michaelwoerister", + "github_id": 1825894, + "is_lead": false + }, + { + "name": "Nell Shamrell-Harrington", + "github": "nellshamrell", + "github_id": 813007, + "is_lead": false + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": false + }, + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": false + }, + { + "name": "Pietro Albini", + "github": "pietroalbini", + "github_id": 2299951, + "is_lead": false + }, + { + "name": "Felix Klock", + "github": "pnkfelix", + "github_id": 173127, + "is_lead": false + }, + { + "name": "Ralf Jung", + "github": "RalfJung", + "github_id": 330628, + "is_lead": false + }, + { + "name": "Robert Collins", + "github": "rbtcollins", + "github_id": 499678, + "is_lead": false + }, + { + "name": "Ramon de C Valle", + "github": "rcvalle", + "github_id": 3988004, + "is_lead": false + }, + { + "name": "Ryan Levick", + "github": "rylev", + "github_id": 1327285, + "is_lead": false + }, + { + "name": "Liv", + "github": "shadows-withal", + "github_id": 6445316, + "is_lead": false + }, + { + "name": "Denis Cornehl", + "github": "syphar", + "github_id": 540890, + "is_lead": false + }, + { + "name": "Tobias Bieniek", + "github": "Turbo87", + "github_id": 141300, + "is_lead": false + }, + { + "name": "Mahmut Bulut", + "github": "vertexclique", + "github_id": 578559, + "is_lead": false + }, + { + "name": "Wesley Wiser", + "github": "wesleywiser", + "github_id": 831192, + "is_lead": false + }, + { + "name": "Jubilee", + "github": "workingjubilee", + "github_id": 46493976, + "is_lead": false + }, + { + "name": "Igor Matuszewski", + "github": "Xanewok", + "github_id": 3093213, + "is_lead": false + }, + { + "name": "Jane Lusby", + "github": "yaahc", + "github_id": 1993852, + "is_lead": false + }, + { + "name": "Yoshua Wuyts", + "github": "yoshuawuyts", + "github_id": 2467194, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "inside-rust-reviewers", + "members": [ + 14791619, + 456674, + 3050060, + 25030997, + 1617736, + 5047365, + 330628, + 141300, + 3093213, + 13042488, + 35149715, + 451806, + 43198, + 9744647, + 31162821, + 162737, + 22186, + 23638587, + 1469421, + 29864074, + 783247, + 1825894, + 813007, + 155238, + 332036, + 2299951, + 173127, + 499678, + 3988004, + 1327285, + 6445316, + 540890, + 578559, + 831192, + 46493976, + 1993852, + 2467194 + ] + } + ] + }, + "website_data": null, + "discord": [] + }, + "lang": { + "name": "lang", + "kind": "team", + "subteam_of": null, + "members": [ + { + "name": "Josh Triplett", + "github": "joshtriplett", + "github_id": 162737, + "is_lead": true + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": true + }, + { + "name": "Felix Klock", + "github": "pnkfelix", + "github_id": 173127, + "is_lead": false + }, + { + "name": "Scott McMurray", + "github": "scottmcm", + "github_id": 18526288, + "is_lead": false + }, + { + "name": "Tyler Mandry", + "github": "tmandry", + "github_id": 2280544, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Mazdak Farrokhzad", + "github": "Centril", + "github_id": 855702, + "is_lead": false + }, + { + "name": "Taylor Cramer", + "github": "cramertj", + "github_id": 5963049, + "is_lead": false + }, + { + "name": "Nick Cameron", + "github": "nrc", + "github_id": 762626, + "is_lead": false + }, + { + "name": "Without Boats", + "github": "withoutboats", + "github_id": 9063376, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "lang", + "members": [ + 162737, + 155238, + 173127, + 18526288, + 2280544 + ] + }, + { + "org": "rust-lang-nursery", + "name": "lang", + "members": [ + 162737, + 155238, + 173127, + 18526288, + 2280544 + ] + } + ] + }, + "website_data": { + "name": "Language team", + "description": "Designing and helping to implement new language features", + "page": "lang", + "email": null, + "repo": "http://github.com/rust-lang/lang-team", + "discord": null, + "zulip_stream": "t-lang", + "weight": 0 + }, + "discord": [] + }, + "lang-advisors": { + "name": "lang-advisors", + "kind": "team", + "subteam_of": "lang", + "members": [ + { + "name": "Alex Crichton", + "github": "alexcrichton", + "github_id": 64996, + "is_lead": false + }, + { + "name": "Amanieu d'Antras", + "github": "Amanieu", + "github_id": 278509, + "is_lead": false + }, + { + "name": "Taylor Cramer", + "github": "cramertj", + "github_id": 5963049, + "is_lead": false + }, + { + "name": "Jack Huey", + "github": "jackh726", + "github_id": 31162821, + "is_lead": false + }, + { + "name": "Jakob Degen", + "github": "JakobDegen", + "github_id": 51179609, + "is_lead": false + }, + { + "name": "Mark Rousskov", + "github": "Mark-Simulacrum", + "github_id": 5047365, + "is_lead": false + }, + { + "name": "Ralf Jung", + "github": "RalfJung", + "github_id": 330628, + "is_lead": false + }, + { + "name": "Wesley Wiser", + "github": "wesleywiser", + "github_id": 831192, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "lang-advisors", + "members": [ + 278509, + 51179609, + 5047365, + 330628, + 64996, + 5963049, + 31162821, + 831192 + ] + } + ] + }, + "website_data": { + "name": "Language Advisors team", + "description": "Advising on the development of the Rust language", + "page": "lang-advisors", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "lang-docs": { + "name": "lang-docs", + "kind": "team", + "subteam_of": "lang", + "members": [ + { + "name": "Eric Huss", + "github": "ehuss", + "github_id": 43198, + "is_lead": true + }, + { + "name": "Yuki Okushi", + "github": "JohnTitor", + "github_id": 25030997, + "is_lead": true + }, + { + "name": "Alexis Beingessner", + "github": "Gankra", + "github_id": 1136864, + "is_lead": false + }, + { + "name": "Ryan Scheel", + "github": "Havvy", + "github_id": 731722, + "is_lead": false + }, + { + "name": "Matthew Jasper", + "github": "matthewjasper", + "github_id": 20113453, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Mazdak Farrokhzad", + "github": "Centril", + "github_id": 855702, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "lang-docs", + "members": [ + 1136864, + 731722, + 25030997, + 43198, + 20113453 + ] + } + ] + }, + "website_data": { + "name": "lang-docs team", + "description": "Developing and writing the docs related to the lang team", + "page": "lang-docs", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": "t-lang/doc", + "weight": 0 + }, + "discord": [] + }, + "leads": { + "name": "leads", + "kind": "team", + "subteam_of": null, + "members": [ + { + "name": "Forest Anderson", + "github": "AngelOnFira", + "github_id": 14791619, + "is_lead": false + }, + { + "name": "Andrew Gallant", + "github": "BurntSushi", + "github_id": 456674, + "is_lead": false + }, + { + "name": "Caleb Cartwright", + "github": "calebcartwright", + "github_id": 13042488, + "is_lead": false + }, + { + "name": "Eric Huss", + "github": "ehuss", + "github_id": 43198, + "is_lead": false + }, + { + "name": "Philipp Krones", + "github": "flip1995", + "github_id": 9744647, + "is_lead": false + }, + { + "name": "Guillaume Gomez", + "github": "GuillaumeGomez", + "github_id": 3050060, + "is_lead": false + }, + { + "name": "Jack Huey", + "github": "jackh726", + "github_id": 31162821, + "is_lead": false + }, + { + "name": "Yuki Okushi", + "github": "JohnTitor", + "github_id": 25030997, + "is_lead": false + }, + { + "name": "Josh Triplett", + "github": "joshtriplett", + "github_id": 162737, + "is_lead": false + }, + { + "name": "Justin Geibel", + "github": "jtgeibel", + "github_id": 22186, + "is_lead": false + }, + { + "name": "Joshua Nelson", + "github": "jyn514", + "github_id": 23638587, + "is_lead": false + }, + { + "name": "Daniel Silverstone", + "github": "kinnison", + "github_id": 1469421, + "is_lead": false + }, + { + "name": "Mara Bos", + "github": "m-ou-se", + "github_id": 783247, + "is_lead": false + }, + { + "name": "Manish Goregaokar", + "github": "Manishearth", + "github_id": 1617736, + "is_lead": false + }, + { + "name": "Mark Rousskov", + "github": "Mark-Simulacrum", + "github_id": 5047365, + "is_lead": false + }, + { + "name": "Nell Shamrell-Harrington", + "github": "nellshamrell", + "github_id": 813007, + "is_lead": false + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": false + }, + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": false + }, + { + "name": "Pietro Albini", + "github": "pietroalbini", + "github_id": 2299951, + "is_lead": false + }, + { + "name": "Felix Klock", + "github": "pnkfelix", + "github_id": 173127, + "is_lead": false + }, + { + "name": "Ralf Jung", + "github": "RalfJung", + "github_id": 330628, + "is_lead": false + }, + { + "name": "Robert Collins", + "github": "rbtcollins", + "github_id": 499678, + "is_lead": false + }, + { + "name": "Ryan Levick", + "github": "rylev", + "github_id": 1327285, + "is_lead": false + }, + { + "name": "Liv", + "github": "shadows-withal", + "github_id": 6445316, + "is_lead": false + }, + { + "name": "Denis Cornehl", + "github": "syphar", + "github_id": 540890, + "is_lead": false + }, + { + "name": "Tobias Bieniek", + "github": "Turbo87", + "github_id": 141300, + "is_lead": false + }, + { + "name": "Mahmut Bulut", + "github": "vertexclique", + "github_id": 578559, + "is_lead": false + }, + { + "name": "Wesley Wiser", + "github": "wesleywiser", + "github_id": 831192, + "is_lead": false + }, + { + "name": "Igor Matuszewski", + "github": "Xanewok", + "github_id": 3093213, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "leads", + "members": [ + 14791619, + 456674, + 3050060, + 25030997, + 1617736, + 5047365, + 330628, + 141300, + 3093213, + 13042488, + 43198, + 9744647, + 31162821, + 162737, + 22186, + 23638587, + 1469421, + 783247, + 813007, + 155238, + 332036, + 2299951, + 173127, + 499678, + 1327285, + 6445316, + 540890, + 578559, + 831192 + ] + } + ] + }, + "website_data": null, + "discord": [] + }, + "libs": { + "name": "libs", + "kind": "team", + "subteam_of": null, + "members": [ + { + "name": "Mara Bos", + "github": "m-ou-se", + "github_id": 783247, + "is_lead": true + }, + { + "name": "Amanieu d'Antras", + "github": "Amanieu", + "github_id": 278509, + "is_lead": false + }, + { + "name": "Josh Stone", + "github": "cuviper", + "github_id": 36186, + "is_lead": false + }, + { + "name": "Josh Triplett", + "github": "joshtriplett", + "github_id": 162737, + "is_lead": false + }, + { + "name": "The 8472", + "github": "the8472", + "github_id": 1065730, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Jane Lusby", + "github": "yaahc", + "github_id": 1993852, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "libs", + "members": [ + 278509, + 36186, + 162737, + 783247, + 1065730 + ] + }, + { + "org": "rust-lang-nursery", + "name": "libs", + "members": [ + 278509, + 36186, + 162737, + 783247, + 1065730 + ] + } + ] + }, + "website_data": { + "name": "Library team", + "description": "Managing and maintaining the Rust standard library and official rust-lang crates", + "page": "library", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": "t-libs", + "weight": 0 + }, + "discord": [] + }, + "libs-api": { + "name": "libs-api", + "kind": "team", + "subteam_of": "libs", + "members": [ + { + "name": "Amanieu d'Antras", + "github": "Amanieu", + "github_id": 278509, + "is_lead": false + }, + { + "name": "Andrew Gallant", + "github": "BurntSushi", + "github_id": 456674, + "is_lead": false + }, + { + "name": "David Tolnay", + "github": "dtolnay", + "github_id": 1940490, + "is_lead": false + }, + { + "name": "Josh Triplett", + "github": "joshtriplett", + "github_id": 162737, + "is_lead": false + }, + { + "name": "Mara Bos", + "github": "m-ou-se", + "github_id": 783247, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Ashley Mannix", + "github": "KodrAus", + "github_id": 6721458, + "is_lead": false + }, + { + "name": "Lukas Kalbertodt", + "github": "LukasKalbertodt", + "github_id": 7419664, + "is_lead": false + }, + { + "name": "Steven Fackler", + "github": "sfackler", + "github_id": 1455697, + "is_lead": false + }, + { + "name": "Simon Sapin", + "github": "SimonSapin", + "github_id": 291359, + "is_lead": false + }, + { + "name": "Without Boats", + "github": "withoutboats", + "github_id": 9063376, + "is_lead": false + }, + { + "name": "Jane Lusby", + "github": "yaahc", + "github_id": 1993852, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "libs-api", + "members": [ + 278509, + 456674, + 1940490, + 162737, + 783247 + ] + }, + { + "org": "rust-lang-nursery", + "name": "libs-api", + "members": [ + 278509, + 456674, + 1940490, + 162737, + 783247 + ] + } + ] + }, + "website_data": { + "name": "Library API team", + "description": "Designing and maintaining the standard library API and guarding its stability", + "page": "libs-api", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 100 + }, + "discord": [] + }, + "libs-contributors": { + "name": "libs-contributors", + "kind": "team", + "subteam_of": "libs", + "members": [ + { + "name": "Chris Denton", + "github": "ChrisDenton", + "github_id": 4459874, + "is_lead": false + }, + { + "name": "Taylor Cramer", + "github": "cramertj", + "github_id": 5963049, + "is_lead": false + }, + { + "name": "David Tolnay", + "github": "dtolnay", + "github_id": 1940490, + "is_lead": false + }, + { + "name": "Yuki Okushi", + "github": "JohnTitor", + "github_id": 25030997, + "is_lead": false + }, + { + "name": "kennytm", + "github": "kennytm", + "github_id": 103023, + "is_lead": false + }, + { + "name": "Ashley Mannix", + "github": "KodrAus", + "github_id": 6721458, + "is_lead": false + }, + { + "name": "Mark Rousskov", + "github": "Mark-Simulacrum", + "github_id": 5047365, + "is_lead": false + }, + { + "name": "Simon Sapin", + "github": "SimonSapin", + "github_id": 291359, + "is_lead": false + }, + { + "name": "Dan Gohman", + "github": "sunfishcode", + "github_id": 4503403, + "is_lead": false + }, + { + "name": "Thom Chiovoloni", + "github": "thomcc", + "github_id": 860665, + "is_lead": false + }, + { + "name": "Jubilee", + "github": "workingjubilee", + "github_id": 46493976, + "is_lead": false + }, + { + "name": "Jane Lusby", + "github": "yaahc", + "github_id": 1993852, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "libs-contributors", + "members": [ + 4459874, + 25030997, + 6721458, + 5047365, + 291359, + 5963049, + 1940490, + 103023, + 4503403, + 860665, + 46493976, + 1993852 + ] + }, + { + "org": "rust-lang-nursery", + "name": "libs-contributors", + "members": [ + 4459874, + 25030997, + 6721458, + 5047365, + 291359, + 5963049, + 1940490, + 103023, + 4503403, + 860665, + 46493976, + 1993852 + ] + } + ] + }, + "website_data": { + "name": "Library contributors", + "description": "Contributing to the Rust standard library on a regular basis", + "page": "libs-contributors", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": -100 + }, + "discord": [] + }, + "macos": { + "name": "macos", + "kind": "marker_team", + "subteam_of": null, + "members": [ + { + "name": "Hans Kratz", + "github": "hkratz", + "github_id": 3736990, + "is_lead": false + }, + { + "name": "Inflation", + "github": "inflation", + "github_id": 2375962, + "is_lead": false + }, + { + "name": "Nikolai Vazquez", + "github": "nvzqz", + "github_id": 10367662, + "is_lead": false + }, + { + "name": "Jake Goulding", + "github": "shepmaster", + "github_id": 174509, + "is_lead": false + }, + { + "name": "Thom Chiovoloni", + "github": "thomcc", + "github_id": 860665, + "is_lead": false + } + ], + "alumni": [], + "github": null, + "website_data": null, + "discord": [] + }, + "miri": { + "name": "miri", + "kind": "team", + "subteam_of": "compiler", + "members": [ + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": true + }, + { + "name": "Ralf Jung", + "github": "RalfJung", + "github_id": 330628, + "is_lead": true + }, + { + "name": "Ben Kimock", + "github": "saethlin", + "github_id": 12105168, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Scott Olson", + "github": "solson", + "github_id": 26806, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "miri", + "members": [ + 330628, + 332036, + 12105168 + ] + } + ] + }, + "website_data": { + "name": "Miri", + "description": "Designing and implementing the Miri interpreter", + "page": "miri", + "email": null, + "repo": "https://github.com/rust-lang/miri", + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "mods": { + "name": "mods", + "kind": "team", + "subteam_of": null, + "members": [ + { + "name": "Khionu Sybiern", + "github": "khionu", + "github_id": 11195266, + "is_lead": false + }, + { + "name": "Olive Gould", + "github": "technetos", + "github_id": 10949810, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Andrew Gallant", + "github": "BurntSushi", + "github_id": 456674, + "is_lead": false + }, + { + "name": "Andre Bogus", + "github": "llogiq", + "github_id": 4200835, + "is_lead": false + }, + { + "name": "Matthieu M.", + "github": "matthieu-m", + "github_id": 2420441, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "mods", + "members": [ + 11195266, + 10949810 + ] + }, + { + "org": "rust-lang-nursery", + "name": "mods", + "members": [ + 11195266, + 10949810 + ] + } + ] + }, + "website_data": { + "name": "Moderation team", + "description": "Helping uphold the code of conduct and community standards", + "page": "moderation", + "email": "rust-mods@rust-lang.org", + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "mods-discord": { + "name": "mods-discord", + "kind": "team", + "subteam_of": "mods", + "members": [ + { + "name": "Khionu Sybiern", + "github": "khionu", + "github_id": 11195266, + "is_lead": false + }, + { + "name": "Manish Goregaokar", + "github": "Manishearth", + "github_id": 1617736, + "is_lead": false + }, + { + "name": "Sage Griffin", + "github": "sgrif", + "github_id": 1529387, + "is_lead": false + }, + { + "name": "Olive Gould", + "github": "technetos", + "github_id": 10949810, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Mazdak Farrokhzad", + "github": "Centril", + "github_id": 855702, + "is_lead": false + }, + { + "name": "Liv", + "github": "shadows-withal", + "github_id": 6445316, + "is_lead": false + } + ], + "github": null, + "website_data": { + "name": "Discord moderators", + "description": "Moderating the Discord server", + "page": "mods-discord", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [ + { + "name": "mods", + "members": [ + 443810603417731092, + 96642168176807936, + 278623213448331265, + 232888196063690752 + ], + "color": "#e74c3c" + } + ] + }, + "mods-discourse": { + "name": "mods-discourse", + "kind": "team", + "subteam_of": "mods", + "members": [ + { + "name": "Khionu Sybiern", + "github": "khionu", + "github_id": 11195266, + "is_lead": false + }, + { + "name": "Michael Howell", + "github": "notriddle", + "github_id": 1593513, + "is_lead": false + }, + { + "name": "Olive Gould", + "github": "technetos", + "github_id": 10949810, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Matt Brubeck", + "github": "mbrubeck", + "github_id": 5920, + "is_lead": false + } + ], + "github": null, + "website_data": { + "name": "Discourse moderators", + "description": "Moderating users.rust-lang.org and internals.rust-lang.org", + "page": "mods-discourse", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "project-async-crashdump-debugging": { + "name": "project-async-crashdump-debugging", + "kind": "project_group", + "subteam_of": "wg-async", + "members": [ + { + "name": "Michael Woerister", + "github": "michaelwoerister", + "github_id": 1825894, + "is_lead": true + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "initiative-async-crashdump-debugging", + "members": [ + 1825894 + ] + } + ] + }, + "website_data": { + "name": "Async Crashdump Debugging Initiative", + "description": "Simplify crashdump debugging of async programs", + "page": "project-async-crashdump-debugging", + "email": null, + "repo": "https://github.com/rust-lang/async-crashdump-debugging-initiative", + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "project-const-generics": { + "name": "project-const-generics", + "kind": "project_group", + "subteam_of": "lang", + "members": [ + { + "name": "lcnr", + "github": "lcnr", + "github_id": 29864074, + "is_lead": true + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": true + }, + { + "name": "Boxy", + "github": "BoxyUwU", + "github_id": 21149742, + "is_lead": false + }, + { + "name": "David Wood", + "github": "davidtwco", + "github_id": 1295100, + "is_lead": false + }, + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": false + }, + { + "name": "varkor", + "github": "varkor", + "github_id": 3943692, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Without Boats", + "github": "withoutboats", + "github_id": 9063376, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "project-const-generics", + "members": [ + 21149742, + 1295100, + 29864074, + 155238, + 332036, + 3943692 + ] + } + ] + }, + "website_data": { + "name": "Const Generics Project Group", + "description": "Working to advance const generics support in the Rust language", + "page": "project-const-generics", + "email": null, + "repo": "https://github.com/rust-lang/project-const-generics", + "discord": null, + "zulip_stream": "project-const-generics", + "weight": 0 + }, + "discord": [] + }, + "project-dyn-upcasting": { + "name": "project-dyn-upcasting", + "kind": "project_group", + "subteam_of": "lang", + "members": [ + { + "name": "Charles Lew", + "github": "crlf0710", + "github_id": 451806, + "is_lead": true + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "initiative-dyn-upcasting", + "members": [ + 451806, + 155238 + ] + } + ] + }, + "website_data": { + "name": "Dyn Upcasting Initiative", + "description": "Allowing Upcasting between trait objects", + "page": "project-dyn-upcasting", + "email": null, + "repo": "https://github.com/rust-lang/dyn-upcasting-coercion-initiative", + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "project-edition-2021": { + "name": "project-edition-2021", + "kind": "project_group", + "subteam_of": "core", + "members": [ + { + "name": "Mara Bos", + "github": "m-ou-se", + "github_id": 783247, + "is_lead": true + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": true + }, + { + "name": "Ryan Levick", + "github": "rylev", + "github_id": 1327285, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "project-edition-2021", + "members": [ + 783247, + 155238, + 1327285 + ] + } + ] + }, + "website_data": { + "name": "Edition 2021 Project Group", + "description": "Managing the Rust 2021 edition", + "page": "project-edition-2021", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": "edition 2021", + "weight": 0 + }, + "discord": [] + }, + "project-error-handling": { + "name": "project-error-handling", + "kind": "project_group", + "subteam_of": "libs", + "members": [ + { + "name": "Jane Lusby", + "github": "yaahc", + "github_id": 1993852, + "is_lead": true + }, + { + "name": "Andrew Gallant", + "github": "BurntSushi", + "github_id": 456674, + "is_lead": false + }, + { + "name": "Jakub Duchniewicz", + "github": "JDuchniewicz", + "github_id": 18423461, + "is_lead": false + }, + { + "name": "oliver", + "github": "kw-fn", + "github_id": 16816606, + "is_lead": false + }, + { + "name": "Nika Layzell", + "github": "mystor", + "github_id": 1261662, + "is_lead": false + }, + { + "name": "Charles \"Chas\" O'Riley", + "github": "nagashi", + "github_id": 1844327, + "is_lead": false + }, + { + "name": "Sean Chen", + "github": "seanchen1991", + "github_id": 4572868, + "is_lead": false + }, + { + "name": "Senyo Simpson", + "github": "senyosimpson", + "github_id": 31822321, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "project-error-handling", + "members": [ + 456674, + 18423461, + 16816606, + 1261662, + 1844327, + 4572868, + 31822321, + 1993852 + ] + } + ] + }, + "website_data": { + "name": "Error Handling Project Group", + "description": "Identifying error handling best practices and consolidating the ecosystem", + "page": "project-error-handling", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "project-exploit-mitigations": { + "name": "project-exploit-mitigations", + "kind": "project_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Ramon de C Valle", + "github": "rcvalle", + "github_id": 3988004, + "is_lead": true + }, + { + "name": "Josh Stone", + "github": "cuviper", + "github_id": 36186, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "project-exploit-mitigations", + "members": [ + 36186, + 3988004 + ] + } + ] + }, + "website_data": { + "name": "Exploit Mitigations Project Group", + "description": "Maintaining and improving the existing, implementing, and researching new exploit mitigations for the Rust compiler", + "page": "project-exploit-mitigations", + "email": null, + "repo": "https://github.com/rust-lang/project-exploit-mitigations", + "discord": null, + "zulip_stream": "project-exploit-mitigations", + "weight": 0 + }, + "discord": [] + }, + "project-generic-associated-types": { + "name": "project-generic-associated-types", + "kind": "project_group", + "subteam_of": "lang", + "members": [ + { + "name": "Jack Huey", + "github": "jackh726", + "github_id": 31162821, + "is_lead": true + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "initiative-generic-associated-types", + "members": [ + 31162821, + 155238 + ] + } + ] + }, + "website_data": { + "name": "Generic Associated Types Initiative", + "description": "Extending Rust with Generic Associated Types", + "page": "project-generic-associated-types", + "email": null, + "repo": "https://github.com/rust-lang/generic-associated-types-initiative", + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "project-impl-trait": { + "name": "project-impl-trait", + "kind": "project_group", + "subteam_of": "lang", + "members": [ + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": true + }, + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "initiative-impl-trait", + "members": [ + 155238, + 332036 + ] + } + ] + }, + "website_data": { + "name": "Impl Trait Initiative", + "description": "Extending Rust with Impl Trait", + "page": "project-impl-trait", + "email": null, + "repo": "https://github.com/rust-lang/impl-trait-initiative", + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "project-keyword-generics": { + "name": "project-keyword-generics", + "kind": "project_group", + "subteam_of": "lang", + "members": [ + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": true + }, + { + "name": "Yoshua Wuyts", + "github": "yoshuawuyts", + "github_id": 2467194, + "is_lead": true + }, + { + "name": "lcnr", + "github": "lcnr", + "github_id": 29864074, + "is_lead": false + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "initiative-keyword-generics", + "members": [ + 29864074, + 155238, + 332036, + 2467194 + ] + } + ] + }, + "website_data": { + "name": "Keyword Generics Initiative", + "description": "Extending the type system to support keyword generics", + "page": "project-keyword-generics", + "email": null, + "repo": "https://github.com/rust-lang/keyword-generics-initiative", + "discord": null, + "zulip_stream": "t-lang/keyword-generics", + "weight": 0 + }, + "discord": [] + }, + "project-negative-impls": { + "name": "project-negative-impls", + "kind": "project_group", + "subteam_of": "lang", + "members": [ + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": true + }, + { + "name": "Felix Klock", + "github": "pnkfelix", + "github_id": 173127, + "is_lead": true + }, + { + "name": "Santiago Pastorino", + "github": "spastorino", + "github_id": 52642, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "initiative-negative-impls", + "members": [ + 155238, + 173127, + 52642 + ] + } + ] + }, + "website_data": { + "name": "Negative Impls Initiative", + "description": "Extending negative impls and integrating them into coherence", + "page": "project-negative-impls", + "email": null, + "repo": "https://github.com/rust-lang/negative-impls-initiative", + "discord": null, + "zulip_stream": "wg-traits", + "weight": 0 + }, + "discord": [] + }, + "project-portable-simd": { + "name": "project-portable-simd", + "kind": "project_group", + "subteam_of": "libs", + "members": [ + { + "name": "Jubilee", + "github": "workingjubilee", + "github_id": 46493976, + "is_lead": true + }, + { + "name": "Andrew Gallant", + "github": "BurntSushi", + "github_id": 456674, + "is_lead": false + }, + { + "name": "Caleb Zulawski", + "github": "calebzulawski", + "github_id": 563826, + "is_lead": false + }, + { + "name": "Henri Sivonen", + "github": "hsivonen", + "github_id": 478856, + "is_lead": false + }, + { + "name": "Jacob Lifshay", + "github": "programmerjake", + "github_id": 4584340, + "is_lead": false + }, + { + "name": "Thom Chiovoloni", + "github": "thomcc", + "github_id": 860665, + "is_lead": false + }, + { + "name": "Mahmut Bulut", + "github": "vertexclique", + "github_id": 578559, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Daniel Gee", + "github": "Lokathor", + "github_id": 5456384, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "project-portable-simd", + "members": [ + 456674, + 563826, + 478856, + 4584340, + 860665, + 578559, + 46493976 + ] + } + ] + }, + "website_data": { + "name": "Portable SIMD Project Group", + "description": "Adding portable SIMD to the standard library", + "page": "project-portable-simd", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "project-stable-mir": { + "name": "project-stable-mir", + "kind": "project_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Celina V.", + "github": "celinval", + "github_id": 35149715, + "is_lead": true + }, + { + "name": "Felix Klock", + "github": "pnkfelix", + "github_id": 173127, + "is_lead": true + }, + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "project-stable-mir", + "members": [ + 35149715, + 332036, + 173127 + ] + } + ] + }, + "website_data": { + "name": "Stable MIR Project Group", + "description": "Define compiler intermediate representation usable by external tools", + "page": "project-stable-mir", + "email": null, + "repo": "https://github.com/rust-lang/project-stable-mir", + "discord": null, + "zulip_stream": "project-stable-mir", + "weight": 0 + }, + "discord": [] + }, + "project-thir-unsafeck": { + "name": "project-thir-unsafeck", + "kind": "project_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": true + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "project-thir-unsafeck", + "members": [ + 155238 + ] + } + ] + }, + "website_data": { + "name": "THIR Unsafety Checker Project Group", + "description": "Working on refactoring unsafety checking to operate on THIR", + "page": "project-thir-unsafeck", + "email": null, + "repo": "https://github.com/rust-lang/project-thir-unsafeck", + "discord": null, + "zulip_stream": "project-thir-unsafeck", + "weight": 0 + }, + "discord": [] + }, + "project-trait-system-refactor": { + "name": "project-trait-system-refactor", + "kind": "project_group", + "subteam_of": "compiler", + "members": [ + { + "name": "lcnr", + "github": "lcnr", + "github_id": 29864074, + "is_lead": true + }, + { + "name": "Boxy", + "github": "BoxyUwU", + "github_id": 21149742, + "is_lead": false + }, + { + "name": "Camille Gillot", + "github": "cjgillot", + "github_id": 1822483, + "is_lead": false + }, + { + "name": "Michael Goulet", + "github": "compiler-errors", + "github_id": 3674314, + "is_lead": false + }, + { + "name": "Santiago Pastorino", + "github": "spastorino", + "github_id": 52642, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "initiative-trait-system-refactor", + "members": [ + 21149742, + 1822483, + 3674314, + 29864074, + 52642 + ] + } + ] + }, + "website_data": { + "name": "Rustc Trait System Refactor Initiative", + "description": "Refactoring the trait system of rustc", + "page": "project-trait-system-refactor", + "email": null, + "repo": "https://github.com/rust-lang/types-team", + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "regex": { + "name": "regex", + "kind": "team", + "subteam_of": "libs", + "members": [ + { + "name": "Andrew Gallant", + "github": "BurntSushi", + "github_id": 456674, + "is_lead": true + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "regex", + "members": [ + 456674 + ] + } + ] + }, + "website_data": { + "name": "Regex crate team", + "description": "Developing and maintaining the regex crate", + "page": "regex", + "email": null, + "repo": "https://github.com/rust-lang/regex", + "discord": null, + "zulip_stream": null, + "weight": -250 + }, + "discord": [] + }, + "release": { + "name": "release", + "kind": "team", + "subteam_of": null, + "members": [ + { + "name": "Mark Rousskov", + "github": "Mark-Simulacrum", + "github_id": 5047365, + "is_lead": true + }, + { + "name": "Josh Stone", + "github": "cuviper", + "github_id": 36186, + "is_lead": false + }, + { + "name": "Dylan DPC", + "github": "Dylan-DPC", + "github_id": 99973273, + "is_lead": false + }, + { + "name": "Pietro Albini", + "github": "pietroalbini", + "github_id": 2299951, + "is_lead": false + }, + { + "name": "Tyler Mandry", + "github": "tmandry", + "github_id": 2280544, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Kyle J Strand", + "github": "BatmanAoD", + "github_id": 2313807, + "is_lead": false + }, + { + "name": "Mazdak Farrokhzad", + "github": "Centril", + "github_id": 855702, + "is_lead": false + }, + { + "name": "Jonas Schievink", + "github": "jonas-schievink", + "github_id": 1786438, + "is_lead": false + }, + { + "name": "Sage Griffin", + "github": "sgrif", + "github_id": 1529387, + "is_lead": false + }, + { + "name": "Erin Power", + "github": "XAMPPRocky", + "github_id": 4464295, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "release", + "members": [ + 99973273, + 5047365, + 36186, + 2299951, + 2280544 + ] + } + ] + }, + "website_data": { + "name": "Release team", + "description": "Tracking regressions and stabilizations, and producing Rust releases", + "page": "release", + "email": "release@rust-lang.org", + "repo": null, + "discord": null, + "zulip_stream": "t-release", + "weight": 0 + }, + "discord": [] + }, + "release-publishers": { + "name": "release-publishers", + "kind": "team", + "subteam_of": "release", + "members": [ + { + "name": "Mark Rousskov", + "github": "Mark-Simulacrum", + "github_id": 5047365, + "is_lead": false + }, + { + "name": "Pietro Albini", + "github": "pietroalbini", + "github_id": 2299951, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "release-publishers", + "members": [ + 5047365, + 2299951 + ] + } + ] + }, + "website_data": null, + "discord": [] + }, + "risc-v": { + "name": "risc-v", + "kind": "marker_team", + "subteam_of": null, + "members": [ + { + "name": "Denis Vasilik", + "github": "denisvasilik", + "github_id": 18697981, + "is_lead": false + }, + { + "name": "Vadim Kaushan", + "github": "Disasm", + "github_id": 1418749, + "is_lead": false + }, + { + "name": "Khem Raj", + "github": "kraj", + "github_id": 465279, + "is_lead": false + }, + { + "name": "Tom Eccles", + "github": "tblah", + "github_id": 3716681, + "is_lead": false + } + ], + "alumni": [], + "github": null, + "website_data": null, + "discord": [] + }, + "rustconf-emails": { + "name": "rustconf-emails", + "kind": "marker_team", + "subteam_of": null, + "members": [], + "alumni": [], + "github": null, + "website_data": null, + "discord": [] + }, + "rustdoc": { + "name": "rustdoc", + "kind": "team", + "subteam_of": "devtools", + "members": [ + { + "name": "Guillaume Gomez", + "github": "GuillaumeGomez", + "github_id": 3050060, + "is_lead": true + }, + { + "name": "Nixon Enraght-Moony", + "github": "aDotInTheVoid", + "github_id": 28781354, + "is_lead": false + }, + { + "name": "Noah Lev", + "github": "camelid", + "github_id": 37223377, + "is_lead": false + }, + { + "name": "Jacob Hoffman-Andrews", + "github": "jsha", + "github_id": 220205, + "is_lead": false + }, + { + "name": "Manish Goregaokar", + "github": "Manishearth", + "github_id": 1617736, + "is_lead": false + }, + { + "name": "Wim", + "github": "Nemo157", + "github_id": 81079, + "is_lead": false + }, + { + "name": "Michael Howell", + "github": "notriddle", + "github_id": 1593513, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Jakob Wiesmore", + "github": "CraftSpider", + "github_id": 13342132, + "is_lead": false + }, + { + "name": "Joshua Nelson", + "github": "jyn514", + "github_id": 23638587, + "is_lead": false + }, + { + "name": "Daniel Silverstone", + "github": "kinnison", + "github_id": 1469421, + "is_lead": false + }, + { + "name": "Oliver Middleton", + "github": "ollie27", + "github_id": 7189418, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "rustdoc", + "members": [ + 3050060, + 1617736, + 81079, + 28781354, + 37223377, + 220205, + 1593513 + ] + }, + { + "org": "rust-lang-nursery", + "name": "rustdoc", + "members": [ + 3050060, + 1617736, + 81079, + 28781354, + 37223377, + 220205, + 1593513 + ] + } + ] + }, + "website_data": { + "name": "Rustdoc team", + "description": "Developing and managing the Rustdoc documentation tool", + "page": "rustdoc", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": "rustdoc", + "weight": 0 + }, + "discord": [] + }, + "rustfmt": { + "name": "rustfmt", + "kind": "team", + "subteam_of": "devtools", + "members": [ + { + "name": "Caleb Cartwright", + "github": "calebcartwright", + "github_id": 13042488, + "is_lead": true + }, + { + "name": "Yacin Tmimi", + "github": "ytmimi", + "github_id": 29028348, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Nick Cameron", + "github": "nrc", + "github_id": 762626, + "is_lead": false + }, + { + "name": "Stéphane Campinas", + "github": "scampi", + "github_id": 795879, + "is_lead": false + }, + { + "name": "Seiichi Uchida", + "github": "topecongiro", + "github_id": 21980157, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "rustfmt", + "members": [ + 13042488, + 29028348 + ] + } + ] + }, + "website_data": { + "name": "Rustfmt team", + "description": "Designing and implementing rustfmt, a formatting tool for Rust code", + "page": "rustfmt", + "email": null, + "repo": null, + "discord": { + "channel": "#wg-rustfmt", + "url": "https://discord.gg/e6Q3cvu" + }, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "rustup": { + "name": "rustup", + "kind": "team", + "subteam_of": "devtools", + "members": [ + { + "name": "Daniel Silverstone", + "github": "kinnison", + "github_id": 1469421, + "is_lead": true + }, + { + "name": "Robert Collins", + "github": "rbtcollins", + "github_id": 499678, + "is_lead": true + }, + { + "name": "二手掉包工程师", + "github": "hi-rustin", + "github_id": 29879298, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Nick Cameron", + "github": "nrc", + "github_id": 762626, + "is_lead": false + } + ], + "github": null, + "website_data": { + "name": "Rustup team", + "description": "Designing and implementing rustup", + "page": "rustup", + "email": null, + "repo": null, + "discord": { + "channel": "#wg-rustup", + "url": "https://discord.gg/e6Q3cvu" + }, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "style": { + "name": "style", + "kind": "team", + "subteam_of": "lang", + "members": [ + { + "name": "Caleb Cartwright", + "github": "calebcartwright", + "github_id": 13042488, + "is_lead": true + }, + { + "name": "Michael Goulet", + "github": "compiler-errors", + "github_id": 3674314, + "is_lead": false + }, + { + "name": "Josh Triplett", + "github": "joshtriplett", + "github_id": 162737, + "is_lead": false + }, + { + "name": "Jane Lusby", + "github": "yaahc", + "github_id": 1993852, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "style", + "members": [ + 13042488, + 3674314, + 162737, + 1993852 + ] + } + ] + }, + "website_data": { + "name": "Style team", + "description": "Defining and evolving the default Rust coding style", + "page": "style", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": "t-style", + "weight": 0 + }, + "discord": [] + }, + "twir": { + "name": "twir", + "kind": "team", + "subteam_of": null, + "members": [ + { + "name": "Nell Shamrell-Harrington", + "github": "nellshamrell", + "github_id": 813007, + "is_lead": true + }, + { + "name": "andrewpollack", + "github": "andrewpollack", + "github_id": 24868505, + "is_lead": false + }, + { + "name": "Colton Donnelly", + "github": "cdmistman", + "github_id": 23486351, + "is_lead": false + }, + { + "name": "Stephan D.", + "github": "extrawurst", + "github_id": 776816, + "is_lead": false + }, + { + "name": "Joel Marcey", + "github": "JoelMarcey", + "github_id": 3757713, + "is_lead": false + }, + { + "name": "Andre Bogus", + "github": "llogiq", + "github_id": 4200835, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Vikrant Chaudhary", + "github": "nasa42", + "github_id": 233999, + "is_lead": false + } + ], + "github": null, + "website_data": null, + "discord": [] + }, + "twir-reviewers": { + "name": "twir-reviewers", + "kind": "team", + "subteam_of": "twir", + "members": [ + { + "name": "Nell Shamrell-Harrington", + "github": "nellshamrell", + "github_id": 813007, + "is_lead": true + }, + { + "name": "andrewpollack", + "github": "andrewpollack", + "github_id": 24868505, + "is_lead": false + }, + { + "name": "benny Vasquez", + "github": "bennyvasquez", + "github_id": 13630986, + "is_lead": false + }, + { + "name": "Colton Donnelly", + "github": "cdmistman", + "github_id": 23486351, + "is_lead": false + }, + { + "name": "Eric Seppanen", + "github": "ericseppanen", + "github_id": 36317762, + "is_lead": false + }, + { + "name": "Stephan D.", + "github": "extrawurst", + "github_id": 776816, + "is_lead": false + }, + { + "name": "M Goldin", + "github": "mariannegoldin", + "github_id": 23177337, + "is_lead": false + }, + { + "name": "Brad Gibson", + "github": "U007D", + "github_id": 2874989, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "twir-reviewers", + "members": [ + 2874989, + 24868505, + 13630986, + 23486351, + 36317762, + 776816, + 23177337, + 813007 + ] + } + ] + }, + "website_data": null, + "discord": [] + }, + "twitter": { + "name": "twitter", + "kind": "marker_team", + "subteam_of": null, + "members": [ + { + "name": "Jan-Erik Rediger", + "github": "badboy", + "github_id": 2129, + "is_lead": false + }, + { + "name": "Josh Triplett", + "github": "joshtriplett", + "github_id": 162737, + "is_lead": false + }, + { + "name": "Mara Bos", + "github": "m-ou-se", + "github_id": 783247, + "is_lead": false + }, + { + "name": "Pietro Albini", + "github": "pietroalbini", + "github_id": 2299951, + "is_lead": false + }, + { + "name": "Ryan Levick", + "github": "rylev", + "github_id": 1327285, + "is_lead": false + } + ], + "alumni": [], + "github": null, + "website_data": null, + "discord": [] + }, + "types": { + "name": "types", + "kind": "team", + "subteam_of": "compiler", + "members": [ + { + "name": "Jack Huey", + "github": "jackh726", + "github_id": 31162821, + "is_lead": true + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": true + }, + { + "name": "Michael Goulet", + "github": "compiler-errors", + "github_id": 3674314, + "is_lead": false + }, + { + "name": "lcnr", + "github": "lcnr", + "github_id": 29864074, + "is_lead": false + }, + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": false + }, + { + "name": "Santiago Pastorino", + "github": "spastorino", + "github_id": 52642, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "types", + "members": [ + 3674314, + 31162821, + 29864074, + 155238, + 332036, + 52642 + ] + }, + { + "org": "rust-lang-nursery", + "name": "types", + "members": [ + 3674314, + 31162821, + 29864074, + 155238, + 332036, + 52642 + ] + } + ] + }, + "website_data": { + "name": "Types team", + "description": "Working to implement and formally define the semantics of the Rust language", + "page": "types", + "email": null, + "repo": "https://github.com/rust-lang/types-team", + "discord": null, + "zulip_stream": "t-types", + "weight": 0 + }, + "discord": [] + }, + "vim": { + "name": "vim", + "kind": "marker_team", + "subteam_of": null, + "members": [ + { + "name": "Chris Morgan", + "github": "chris-morgan", + "github_id": 392868, + "is_lead": false + }, + { + "name": "Dan Aloni", + "github": "da-x", + "github_id": 321273, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "vim", + "members": [ + 392868, + 321273 + ] + } + ] + }, + "website_data": null, + "discord": [] + }, + "web-presence": { + "name": "web-presence", + "kind": "team", + "subteam_of": null, + "members": [], + "alumni": [], + "github": null, + "website_data": null, + "discord": [] + }, + "website": { + "name": "website", + "kind": "team", + "subteam_of": "web-presence", + "members": [ + { + "name": "Manish Goregaokar", + "github": "Manishearth", + "github_id": 1617736, + "is_lead": true + } + ], + "alumni": [ + { + "name": "Pietro Albini", + "github": "pietroalbini", + "github_id": 2299951, + "is_lead": false + }, + { + "name": "Florian Gilcher", + "github": "skade", + "github_id": 47542, + "is_lead": false + }, + { + "name": "Erin Power", + "github": "XAMPPRocky", + "github_id": 4464295, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "website", + "members": [ + 1617736 + ] + } + ] + }, + "website_data": null, + "discord": [] + }, + "wg-allocators": { + "name": "wg-allocators", + "kind": "working_group", + "subteam_of": "libs", + "members": [ + { + "name": "Tim Diekmann", + "github": "TimDiekmann", + "github_id": 21277928, + "is_lead": true + }, + { + "name": "Amanieu d'Antras", + "github": "Amanieu", + "github_id": 278509, + "is_lead": false + }, + { + "name": "Christopher Durham", + "github": "CAD97", + "github_id": 5992217, + "is_lead": false + }, + { + "name": "Daniel Gee", + "github": "Lokathor", + "github_id": 5456384, + "is_lead": false + }, + { + "name": "Scott J Maddox", + "github": "scottjmaddox", + "github_id": 28676699, + "is_lead": false + }, + { + "name": "Remco", + "github": "Wodann", + "github_id": 6917585, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-allocators", + "members": [ + 278509, + 5992217, + 5456384, + 21277928, + 6917585, + 28676699 + ] + } + ] + }, + "website_data": { + "name": "Allocator working group", + "description": "Paving a path for a standard set of allocator traits to be used in collections", + "page": "wg-allocators", + "email": null, + "repo": "https://github.com/rust-lang/wg-allocators", + "discord": null, + "zulip_stream": "t-libs/wg-allocators", + "weight": 0 + }, + "discord": [] + }, + "wg-async": { + "name": "wg-async", + "kind": "working_group", + "subteam_of": null, + "members": [ + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": true + }, + { + "name": "Tyler Mandry", + "github": "tmandry", + "github_id": 2280544, + "is_lead": true + }, + { + "name": "Eric Holk", + "github": "eholk", + "github_id": 105766, + "is_lead": false + }, + { + "name": "Esteban Kuber", + "github": "estebank", + "github_id": 1606434, + "is_lead": false + }, + { + "name": "Gus Wynn", + "github": "guswynn", + "github_id": 5404303, + "is_lead": false + }, + { + "name": "Michael Woerister", + "github": "michaelwoerister", + "github_id": 1825894, + "is_lead": false + }, + { + "name": "Nick Cameron", + "github": "nrc", + "github_id": 762626, + "is_lead": false + }, + { + "name": "Felix Klock", + "github": "pnkfelix", + "github_id": 173127, + "is_lead": false + }, + { + "name": "Santiago Pastorino", + "github": "spastorino", + "github_id": 52642, + "is_lead": false + }, + { + "name": "Taiki Endo", + "github": "taiki-e", + "github_id": 43724913, + "is_lead": false + }, + { + "name": "Yoshua Wuyts", + "github": "yoshuawuyts", + "github_id": 2467194, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Aaron Hill", + "github": "Aaron1011", + "github_id": 1408859, + "is_lead": false + }, + { + "name": "Didrik Nordström", + "github": "betamos", + "github_id": 135960, + "is_lead": false + }, + { + "name": "Bhargav Voleti", + "github": "bIgBV", + "github_id": 5019938, + "is_lead": false + }, + { + "name": "Taylor Cramer", + "github": "cramertj", + "github_id": 5963049, + "is_lead": false + }, + { + "name": "csmoe", + "github": "csmoe", + "github_id": 35686186, + "is_lead": false + }, + { + "name": "Doc Jones", + "github": "doc-jones", + "github_id": 37349558, + "is_lead": false + }, + { + "name": "Andrew Chin", + "github": "eminence", + "github_id": 402454, + "is_lead": false + }, + { + "name": "Emmanuel Antony", + "github": "emmanuelantony2000", + "github_id": 19288251, + "is_lead": false + }, + { + "name": "Squirrel", + "github": "gilescope", + "github_id": 803976, + "is_lead": false + }, + { + "name": "Lee Bernick", + "github": "lbernick", + "github_id": 29333301, + "is_lead": false + }, + { + "name": "Lucio Franco", + "github": "LucioFranco", + "github_id": 5758045, + "is_lead": false + }, + { + "name": "Nell Shamrell-Harrington", + "github": "nellshamrell", + "github_id": 813007, + "is_lead": false + }, + { + "name": "Ryan Levick", + "github": "rylev", + "github_id": 1327285, + "is_lead": false + }, + { + "name": "Without Boats", + "github": "withoutboats", + "github_id": 9063376, + "is_lead": false + }, + { + "name": "Zeeshan Ali", + "github": "zeenix", + "github_id": 2027, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-async", + "members": [ + 105766, + 1606434, + 5404303, + 1825894, + 155238, + 762626, + 173127, + 52642, + 43724913, + 2280544, + 2467194 + ] + }, + { + "org": "rust-lang-nursery", + "name": "wg-async", + "members": [ + 105766, + 1606434, + 5404303, + 1825894, + 155238, + 762626, + 173127, + 52642, + 43724913, + 2280544, + 2467194 + ] + } + ] + }, + "website_data": { + "name": "Async working group", + "description": "Pursuing core language and library support for async-await", + "page": "wg-async", + "email": null, + "repo": "https://github.com/rust-lang/wg-async", + "discord": null, + "zulip_stream": "wg-async", + "weight": 0 + }, + "discord": [] + }, + "wg-bindgen": { + "name": "wg-bindgen", + "kind": "working_group", + "subteam_of": "devtools", + "members": [ + { + "name": "Emilio Cobos Álvarez", + "github": "emilio", + "github_id": 1323194, + "is_lead": true + }, + { + "name": "Nick Fitzgerald", + "github": "fitzgen", + "github_id": 74571, + "is_lead": true + } + ], + "alumni": [], + "github": null, + "website_data": { + "name": "Bindgen working group", + "description": "Developing tools for generating FFI bindings", + "page": "wg-bindgen", + "email": null, + "repo": "https://github.com/rust-lang-nursery/rust-bindgen", + "discord": { + "channel": "#wg-bindgen", + "url": "https://discord.gg/kgujzMR" + }, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-cli": { + "name": "wg-cli", + "kind": "working_group", + "subteam_of": null, + "members": [ + { + "name": "Ed Page", + "github": "epage", + "github_id": 60961, + "is_lead": true + }, + { + "name": "Daniel Sockwell", + "github": "codesections", + "github_id": 35405463, + "is_lead": false + }, + { + "name": "Ricky", + "github": "deg4uss3r", + "github_id": 15351059, + "is_lead": false + }, + { + "name": "Dylan DPC", + "github": "Dylan-DPC", + "github_id": 99973273, + "is_lead": false + }, + { + "name": "Matthias Beyer", + "github": "matthiasbeyer", + "github_id": 427866, + "is_lead": false + }, + { + "name": "Pavan Kumar Sunkara", + "github": "pksunkara", + "github_id": 174703, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Pascal Hertleif", + "github": "killercup", + "github_id": 20063, + "is_lead": false + }, + { + "name": "Katharina Fey", + "github": "spacekookie", + "github_id": 7669898, + "is_lead": false + }, + { + "name": "Yoshua Wuyts", + "github": "yoshuawuyts", + "github_id": 2467194, + "is_lead": false + } + ], + "github": null, + "website_data": { + "name": "Command-line interfaces (CLI) working group", + "description": "Focusing on the end-to-end experience of writing terminal apps, both large and small, in Rust.", + "page": "cli", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": "wg-cli", + "weight": 0 + }, + "discord": [] + }, + "wg-compiler-performance": { + "name": "wg-compiler-performance", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Mark Rousskov", + "github": "Mark-Simulacrum", + "github_id": 5047365, + "is_lead": true + }, + { + "name": "Jakub Beránek", + "github": "Kobzol", + "github_id": 4539057, + "is_lead": false + }, + { + "name": "Rémy Rakic", + "github": "lqd", + "github_id": 247183, + "is_lead": false + }, + { + "name": "Michael Woerister", + "github": "michaelwoerister", + "github_id": 1825894, + "is_lead": false + }, + { + "name": "Nicholas Nethercote", + "github": "nnethercote", + "github_id": 1940286, + "is_lead": false + }, + { + "name": "Felix Klock", + "github": "pnkfelix", + "github_id": 173127, + "is_lead": false + }, + { + "name": "Ryan Levick", + "github": "rylev", + "github_id": 1327285, + "is_lead": false + }, + { + "name": "Tyson Nottingham", + "github": "tgnottingham", + "github_id": 3668166, + "is_lead": false + }, + { + "name": "Wesley Wiser", + "github": "wesleywiser", + "github_id": 831192, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-compiler-performance", + "members": [ + 4539057, + 5047365, + 247183, + 1825894, + 1940286, + 173127, + 1327285, + 3668166, + 831192 + ] + } + ] + }, + "website_data": { + "name": "Compiler performance working group", + "description": "Improving rustc compilation performance (build times)", + "page": "wg-compiler-performance", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-const-eval": { + "name": "wg-const-eval", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": true + }, + { + "name": "Ralf Jung", + "github": "RalfJung", + "github_id": 330628, + "is_lead": true + }, + { + "name": "Deadbeef", + "github": "fee1-dead", + "github_id": 43851243, + "is_lead": false + }, + { + "name": "lcnr", + "github": "lcnr", + "github_id": 29864074, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Dylan MacKenzie", + "github": "ecstatic-morse", + "github_id": 29463364, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-const-eval", + "members": [ + 330628, + 43851243, + 29864074, + 332036 + ] + } + ] + }, + "website_data": { + "name": "Compile-time Function Evaluation Working Group", + "description": "Soundly expanding the capabilities of compile-time function evaluation in Rust", + "page": "wg-const-eval", + "email": null, + "repo": "https://github.com/rust-lang/const-eval", + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-debugging": { + "name": "wg-debugging", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Felix Klock", + "github": "pnkfelix", + "github_id": 173127, + "is_lead": true + }, + { + "name": "Wesley Wiser", + "github": "wesleywiser", + "github_id": 831192, + "is_lead": true + }, + { + "name": "David Wood", + "github": "davidtwco", + "github_id": 1295100, + "is_lead": false + }, + { + "name": "Michael Woerister", + "github": "michaelwoerister", + "github_id": 1825894, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Manish Goregaokar", + "github": "Manishearth", + "github_id": 1617736, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-debugging", + "members": [ + 1295100, + 1825894, + 173127, + 831192 + ] + } + ] + }, + "website_data": { + "name": "Debugging Working Group", + "description": "Providing users with a great experience when debugging Rust code", + "page": "wg-debugging", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": "t-compiler/wg-debugging", + "weight": 0 + }, + "discord": [] + }, + "wg-diagnostics": { + "name": "wg-diagnostics", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Esteban Kuber", + "github": "estebank", + "github_id": 1606434, + "is_lead": true + }, + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": true + }, + { + "name": "Michael Goulet", + "github": "compiler-errors", + "github_id": 3674314, + "is_lead": false + }, + { + "name": "David Wood", + "github": "davidtwco", + "github_id": 1295100, + "is_lead": false + }, + { + "name": "Yuki Okushi", + "github": "JohnTitor", + "github_id": 25030997, + "is_lead": false + }, + { + "name": "Takayuki Maeda", + "github": "TaKO8Ki", + "github_id": 41065217, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-diagnostics", + "members": [ + 25030997, + 41065217, + 3674314, + 1295100, + 1606434, + 332036 + ] + } + ] + }, + "website_data": { + "name": "Diagnostics working group", + "description": "Aiming to make rustc better at telling the user why the compiler isn't smart enough to understand their code yet", + "page": "wg-diagnostics", + "email": null, + "repo": "https://rust-lang.github.io/compiler-team/working-groups/diagnostics/", + "discord": null, + "zulip_stream": "t-compiler/wg-diagnostics", + "weight": 0 + }, + "discord": [] + }, + "wg-embedded": { + "name": "wg-embedded", + "kind": "working_group", + "subteam_of": null, + "members": [ + { + "name": "Adam Greig", + "github": "adamgreig", + "github_id": 47219, + "is_lead": true + }, + { + "name": "Jorge Aparicio", + "github": "japaric", + "github_id": 5018213, + "is_lead": true + }, + { + "name": "Daniel Egger", + "github": "therealprof", + "github_id": 3321888, + "is_lead": true + }, + { + "name": "Aleš Katona", + "github": "almindor", + "github_id": 1950958, + "is_lead": false + }, + { + "name": "Andre Richter", + "github": "andre-richter", + "github_id": 4130005, + "is_lead": false + }, + { + "name": "Zgarbul Andrey", + "github": "burrbull", + "github_id": 3072754, + "is_lead": false + }, + { + "name": "William D. Jones", + "github": "cr1901", + "github_id": 6418027, + "is_lead": false + }, + { + "name": "Vadim Kaushan", + "github": "Disasm", + "github_id": 1418749, + "is_lead": false + }, + { + "name": "dkhayes117", + "github": "dkhayes117", + "github_id": 59458913, + "is_lead": false + }, + { + "name": "Diego Barrios Romero", + "github": "eldruin", + "github_id": 43125, + "is_lead": false + }, + { + "name": "Emil Gardström", + "github": "Emilgardis", + "github_id": 1502855, + "is_lead": false + }, + { + "name": "Henrik Böving", + "github": "hargoniX", + "github_id": 33270164, + "is_lead": false + }, + { + "name": "Wilfried Chauveau", + "github": "ithinuel", + "github_id": 4605303, + "is_lead": false + }, + { + "name": "James Munns", + "github": "jamesmunns", + "github_id": 2097964, + "is_lead": false + }, + { + "name": "Nick Stevens", + "github": "nastevens", + "github_id": 1500008, + "is_lead": false + }, + { + "name": "Paul Osborne", + "github": "posborne", + "github_id": 41714, + "is_lead": false + }, + { + "name": "Robin Randhawa", + "github": "raw-bin", + "github_id": 705890, + "is_lead": false + }, + { + "name": "Markus Reiter", + "github": "reitermarkus", + "github_id": 1309829, + "is_lead": false + }, + { + "name": "Ryan", + "github": "ryankurte", + "github_id": 860620, + "is_lead": false + }, + { + "name": "Thales", + "github": "thalesfragoso", + "github_id": 46510852, + "is_lead": false + }, + { + "name": "Jonathan Pallant", + "github": "thejpster", + "github_id": 959887, + "is_lead": false + } + ], + "alumni": [ + { + "name": "awygle", + "github": "awygle", + "github_id": 7854806, + "is_lead": false + }, + { + "name": "Brad Campbell", + "github": "bradjc", + "github_id": 1467890, + "is_lead": false + }, + { + "name": "Dan Callaghan", + "github": "danc86", + "github_id": 398575, + "is_lead": false + }, + { + "name": "David Craven", + "github": "dvc94ch", + "github_id": 741807, + "is_lead": false + }, + { + "name": "Dylan McKay", + "github": "dylanmckay", + "github_id": 7722159, + "is_lead": false + }, + { + "name": "Hanno Braun", + "github": "hannobraun", + "github_id": 85732, + "is_lead": false + }, + { + "name": "Wilfried Chauveau", + "github": "ithinuel", + "github_id": 4605303, + "is_lead": false + }, + { + "name": "Jonathan Soo", + "github": "jcsoo", + "github_id": 2399463, + "is_lead": false + }, + { + "name": "Jonas Schievink", + "github": "jonas-schievink", + "github_id": 1786438, + "is_lead": false + }, + { + "name": "Emil Fresk", + "github": "korken89", + "github_id": 913109, + "is_lead": false + }, + { + "name": "Wladimir J. van der Laan", + "github": "laanwj", + "github_id": 126646, + "is_lead": false + }, + { + "name": "Paolo Teti", + "github": "paoloteti", + "github_id": 35451649, + "is_lead": false + }, + { + "name": "James Duley", + "github": "parched", + "github_id": 5975405, + "is_lead": false + }, + { + "name": "Vadzim Dambrouski", + "github": "pftbest", + "github_id": 1573340, + "is_lead": false + }, + { + "name": "Hideki Sekine", + "github": "sekineh", + "github_id": 3956266, + "is_lead": false + }, + { + "name": "vaishali Thakkar", + "github": "v-thakkar", + "github_id": 7105009, + "is_lead": false + }, + { + "name": "Ioannis Valasakis", + "github": "wizofe", + "github_id": 22352218, + "is_lead": false + } + ], + "github": null, + "website_data": { + "name": "Embedded devices working group", + "description": "Focusing on improving the end-to-end experience of using Rust in resource-constrained environments and non-traditional platforms", + "page": "embedded", + "email": null, + "repo": "https://github.com/rust-embedded/wg", + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-embedded-core": { + "name": "wg-embedded-core", + "kind": "working_group", + "subteam_of": "wg-embedded", + "members": [ + { + "name": "Adam Greig", + "github": "adamgreig", + "github_id": 47219, + "is_lead": false + }, + { + "name": "Jorge Aparicio", + "github": "japaric", + "github_id": 5018213, + "is_lead": false + }, + { + "name": "Daniel Egger", + "github": "therealprof", + "github_id": 3321888, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-embedded", + "name": "core", + "members": [ + 47219, + 5018213, + 3321888 + ] + } + ] + }, + "website_data": { + "name": "Embedded core team", + "description": "The core team represents the WG in meetings with the Rust teams", + "page": "wg-embedded-core", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-embedded-cortex-a": { + "name": "wg-embedded-cortex-a", + "kind": "working_group", + "subteam_of": "wg-embedded", + "members": [ + { + "name": "Andre Richter", + "github": "andre-richter", + "github_id": 4130005, + "is_lead": false + }, + { + "name": "Robin Randhawa", + "github": "raw-bin", + "github_id": 705890, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-embedded", + "name": "wg-embedded-cortex-a", + "members": [ + 4130005, + 705890 + ] + } + ] + }, + "website_data": { + "name": "Embedded Cortex-A team", + "description": "Develops and maintains the core of the Cortex-A crate ecosystem ", + "page": "wg-embedded-cortex-a", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-embedded-cortex-m": { + "name": "wg-embedded-cortex-m", + "kind": "working_group", + "subteam_of": "wg-embedded", + "members": [ + { + "name": "Adam Greig", + "github": "adamgreig", + "github_id": 47219, + "is_lead": false + }, + { + "name": "Alex Martens", + "github": "newAM", + "github_id": 7845120, + "is_lead": false + }, + { + "name": "Thales", + "github": "thalesfragoso", + "github_id": 46510852, + "is_lead": false + }, + { + "name": "Jonathan Pallant", + "github": "thejpster", + "github_id": 959887, + "is_lead": false + }, + { + "name": "Daniel Egger", + "github": "therealprof", + "github_id": 3321888, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-embedded", + "name": "wg-embedded-cortex-m", + "members": [ + 47219, + 7845120, + 46510852, + 959887, + 3321888 + ] + } + ] + }, + "website_data": { + "name": "Embedded Cortex-M team", + "description": "Develops and maintains the core of the Cortex-M crate ecosystem ", + "page": "wg-embedded-cortex-m", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-embedded-cortex-r": { + "name": "wg-embedded-cortex-r", + "kind": "working_group", + "subteam_of": "wg-embedded", + "members": [ + { + "name": "Jorge Aparicio", + "github": "japaric", + "github_id": 5018213, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-embedded", + "name": "wg-embedded-cortex-r", + "members": [ + 5018213 + ] + } + ] + }, + "website_data": { + "name": "Embedded Cortex-R team", + "description": "Develops and maintains the core of the Cortex-R crate ecosystem ", + "page": "wg-embedded-cortex-r", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-embedded-hal": { + "name": "wg-embedded-hal", + "kind": "working_group", + "subteam_of": "wg-embedded", + "members": [ + { + "name": "Diego Barrios Romero", + "github": "eldruin", + "github_id": 43125, + "is_lead": false + }, + { + "name": "Ryan", + "github": "ryankurte", + "github_id": 860620, + "is_lead": false + }, + { + "name": "Daniel Egger", + "github": "therealprof", + "github_id": 3321888, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-embedded", + "name": "embedded-hal", + "members": [ + 43125, + 860620, + 3321888 + ] + } + ] + }, + "website_data": { + "name": "Embedded HAL team", + "description": "Develops and maintains crates that ease the development of Hardware Abstraction Layers, Board Support Crates and drivers", + "page": "wg-embedded-hal", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-embedded-infra": { + "name": "wg-embedded-infra", + "kind": "working_group", + "subteam_of": "wg-embedded", + "members": [ + { + "name": "Nick Stevens", + "github": "nastevens", + "github_id": 1500008, + "is_lead": false + }, + { + "name": "Ryan", + "github": "ryankurte", + "github_id": 860620, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-embedded", + "name": "infrastructure", + "members": [ + 1500008, + 860620 + ] + } + ] + }, + "website_data": { + "name": "Embedded infrastructure team", + "description": "Managing infrastructure for wg-embedded", + "page": "wg-embedded-infra", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-embedded-linux": { + "name": "wg-embedded-linux", + "kind": "working_group", + "subteam_of": "wg-embedded", + "members": [ + { + "name": "Diego Barrios Romero", + "github": "eldruin", + "github_id": 43125, + "is_lead": false + }, + { + "name": "Nick Stevens", + "github": "nastevens", + "github_id": 1500008, + "is_lead": false + }, + { + "name": "Paul Osborne", + "github": "posborne", + "github_id": 41714, + "is_lead": false + }, + { + "name": "Ryan", + "github": "ryankurte", + "github_id": 860620, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-embedded", + "name": "embedded-linux", + "members": [ + 43125, + 1500008, + 41714, + 860620 + ] + } + ] + }, + "website_data": { + "name": "Embedded Linux team", + "description": "The embedded Linux team develops and maintains the core of the embedded Linux crate ecosystem.", + "page": "wg-embedded-linux", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-embedded-msp430": { + "name": "wg-embedded-msp430", + "kind": "working_group", + "subteam_of": "wg-embedded", + "members": [ + { + "name": "William D. Jones", + "github": "cr1901", + "github_id": 6418027, + "is_lead": false + }, + { + "name": "Yuhan Lin", + "github": "YuhanLiin", + "github_id": 15389635, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-embedded", + "name": "msp430", + "members": [ + 15389635, + 6418027 + ] + } + ] + }, + "website_data": { + "name": "Embedded MSP430 team", + "description": "Develops and maintains the core of the embedded MSP430 crate ecosystem", + "page": "wg-embedded-msp430", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-embedded-resources": { + "name": "wg-embedded-resources", + "kind": "working_group", + "subteam_of": "wg-embedded", + "members": [ + { + "name": "Adam Greig", + "github": "adamgreig", + "github_id": 47219, + "is_lead": false + }, + { + "name": "Andre Richter", + "github": "andre-richter", + "github_id": 4130005, + "is_lead": false + }, + { + "name": "Diego Barrios Romero", + "github": "eldruin", + "github_id": 43125, + "is_lead": false + }, + { + "name": "Henrik Böving", + "github": "hargoniX", + "github_id": 33270164, + "is_lead": false + }, + { + "name": "James Munns", + "github": "jamesmunns", + "github_id": 2097964, + "is_lead": false + }, + { + "name": "Daniel Egger", + "github": "therealprof", + "github_id": 3321888, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-embedded", + "name": "resources", + "members": [ + 47219, + 4130005, + 43125, + 33270164, + 2097964, + 3321888 + ] + } + ] + }, + "website_data": { + "name": "Embedded resources working group", + "description": "Managing various resources owned by the embedded working group", + "page": "wg-embedded-resources", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-embedded-riscv": { + "name": "wg-embedded-riscv", + "kind": "working_group", + "subteam_of": "wg-embedded", + "members": [ + { + "name": "Aleš Katona", + "github": "almindor", + "github_id": 1950958, + "is_lead": false + }, + { + "name": "Vadim Kaushan", + "github": "Disasm", + "github_id": 1418749, + "is_lead": false + }, + { + "name": "dkhayes117", + "github": "dkhayes117", + "github_id": 59458913, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-embedded", + "name": "risc-v", + "members": [ + 1418749, + 1950958, + 59458913 + ] + } + ] + }, + "website_data": { + "name": "Embedded RISCV team", + "description": "Develops and maintains the core of the embedded RISCV crate ecosystem", + "page": "wg-embedded-riscv", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-embedded-tools": { + "name": "wg-embedded-tools", + "kind": "working_group", + "subteam_of": "wg-embedded", + "members": [ + { + "name": "Adam Greig", + "github": "adamgreig", + "github_id": 47219, + "is_lead": false + }, + { + "name": "Zgarbul Andrey", + "github": "burrbull", + "github_id": 3072754, + "is_lead": false + }, + { + "name": "Emil Gardström", + "github": "Emilgardis", + "github_id": 1502855, + "is_lead": false + }, + { + "name": "Jonathan Pallant", + "github": "jonathanpallant", + "github_id": 18005923, + "is_lead": false + }, + { + "name": "Markus Reiter", + "github": "reitermarkus", + "github_id": 1309829, + "is_lead": false + }, + { + "name": "Ryan", + "github": "ryankurte", + "github_id": 860620, + "is_lead": false + }, + { + "name": "Jonathan Pallant", + "github": "thejpster", + "github_id": 959887, + "is_lead": false + }, + { + "name": "Daniel Egger", + "github": "therealprof", + "github_id": 3321888, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-embedded", + "name": "tools", + "members": [ + 1502855, + 47219, + 3072754, + 18005923, + 1309829, + 860620, + 959887, + 3321888 + ] + } + ] + }, + "website_data": { + "name": "Embedded Tools Team", + "description": "Develops and maintains core embedded tools", + "page": "wg-embedded-tools", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-embedded-triage": { + "name": "wg-embedded-triage", + "kind": "working_group", + "subteam_of": "wg-embedded", + "members": [ + { + "name": "Mathieu Suen", + "github": "mathk", + "github_id": 314381, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-embedded", + "name": "triage", + "members": [ + 314381 + ] + } + ] + }, + "website_data": { + "name": "Embedded Triage Team", + "description": "The triage team keeps PR queues moving; they ensure no PR is left unattended", + "page": "wg-embedded-triage", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-ffi-unwind": { + "name": "wg-ffi-unwind", + "kind": "working_group", + "subteam_of": "lang", + "members": [ + { + "name": "Adam C. Foltzer", + "github": "acfoltzer", + "github_id": 205266, + "is_lead": true + }, + { + "name": "Kyle J Strand", + "github": "BatmanAoD", + "github_id": 2313807, + "is_lead": true + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": true + }, + { + "name": "Amanieu d'Antras", + "github": "Amanieu", + "github_id": 278509, + "is_lead": false + }, + { + "name": "bjorn3", + "github": "bjorn3", + "github_id": 17426603, + "is_lead": false + }, + { + "name": "Christopher Durham", + "github": "CAD97", + "github_id": 5992217, + "is_lead": false + }, + { + "name": "Connor Horman", + "github": "chorman0773", + "github_id": 5026283, + "is_lead": false + }, + { + "name": "Katelyn Martin", + "github": "cratelyn", + "github_id": 57912822, + "is_lead": false + }, + { + "name": "gnzlbg", + "github": "gnzlbg", + "github_id": 904614, + "is_lead": false + }, + { + "name": "Josh Triplett", + "github": "joshtriplett", + "github_id": 162737, + "is_lead": false + }, + { + "name": "Gary Guo", + "github": "nbdd0121", + "github_id": 4065244, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-ffi-unwind", + "members": [ + 278509, + 2313807, + 5992217, + 205266, + 17426603, + 5026283, + 57912822, + 904614, + 162737, + 4065244, + 155238 + ] + } + ] + }, + "website_data": { + "name": "ffi-unwind project group", + "description": "A working-group project to extend the Rust language to support unwinding that crosses FFI boundaries", + "page": "wg-ffi-unwind", + "email": null, + "repo": "https://github.com/rust-lang/project-ffi-unwind", + "discord": null, + "zulip_stream": "project-ffi-unwind", + "weight": 0 + }, + "discord": [] + }, + "wg-gamedev": { + "name": "wg-gamedev", + "kind": "working_group", + "subteam_of": null, + "members": [ + { + "name": "Forest Anderson", + "github": "AngelOnFira", + "github_id": 14791619, + "is_lead": true + }, + { + "name": "Erlend Sogge Heggen", + "github": "erlend-sh", + "github_id": 583842, + "is_lead": true + }, + { + "name": "Dzmitry Malyshau", + "github": "kvark", + "github_id": 107301, + "is_lead": true + }, + { + "name": "Andrey Lesnikov", + "github": "ozkriff", + "github_id": 662976, + "is_lead": true + }, + { + "name": "Joe Clay", + "github": "17cupsofcoffee", + "github_id": 784533, + "is_lead": false + }, + { + "name": "Philip Degarmo", + "github": "aclysma", + "github_id": 316070, + "is_lead": false + }, + { + "name": "Alexandru Ene", + "github": "AlexEne", + "github_id": 5849037, + "is_lead": false + }, + { + "name": "Elina Shakhnovich", + "github": "logicsoup", + "github_id": 20725524, + "is_lead": false + }, + { + "name": "Daniel Gee", + "github": "Lokathor", + "github_id": 5456384, + "is_lead": false + }, + { + "name": "Richard Patching", + "github": "patchfx", + "github_id": 294376, + "is_lead": false + }, + { + "name": "Johan Andersson", + "github": "repi", + "github_id": 1262692, + "is_lead": false + }, + { + "name": "Remco", + "github": "Wodann", + "github_id": 6917585, + "is_lead": false + } + ], + "alumni": [], + "github": null, + "website_data": { + "name": "Game development working group", + "description": "Focusing on making Rust the default choice for game development", + "page": "gamedev", + "email": null, + "repo": "https://github.com/rust-gamedev", + "discord": { + "channel": "#wg-gamedev", + "url": "https://discord.gg/sG23nSS" + }, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-grammar": { + "name": "wg-grammar", + "kind": "working_group", + "subteam_of": "lang", + "members": [ + { + "name": "Eduard-Mihai Burtescu", + "github": "eddyb", + "github_id": 77424, + "is_lead": true + }, + { + "name": "Christopher Durham", + "github": "CAD97", + "github_id": 5992217, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Mazdak Farrokhzad", + "github": "Centril", + "github_id": 855702, + "is_lead": false + }, + { + "name": "Douglas Campos", + "github": "qmx", + "github_id": 66734, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-grammar", + "members": [ + 5992217, + 77424 + ] + } + ] + }, + "website_data": { + "name": "Grammar working group", + "description": "Working out the official, formal grammar for Rust and validating it against existing implementations", + "page": "wg-grammar", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-incr-comp": { + "name": "wg-incr-comp", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Felix Klock", + "github": "pnkfelix", + "github_id": 173127, + "is_lead": true + }, + { + "name": "Wesley Wiser", + "github": "wesleywiser", + "github_id": 831192, + "is_lead": true + }, + { + "name": "Aaron Hill", + "github": "Aaron1011", + "github_id": 1408859, + "is_lead": false + }, + { + "name": "Camille Gillot", + "github": "cjgillot", + "github_id": 1822483, + "is_lead": false + }, + { + "name": "David Wood", + "github": "davidtwco", + "github_id": 1295100, + "is_lead": false + }, + { + "name": "Michael Woerister", + "github": "michaelwoerister", + "github_id": 1825894, + "is_lead": false + }, + { + "name": "Santiago Pastorino", + "github": "spastorino", + "github_id": 52642, + "is_lead": false + } + ], + "alumni": [ + { + "name": "pierwill", + "github": "pierwill", + "github_id": 19642016, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-incr-comp", + "members": [ + 1408859, + 1822483, + 1295100, + 1825894, + 173127, + 52642, + 831192 + ] + } + ] + }, + "website_data": { + "name": "Incremental compilation working group", + "description": "Improving incremental compilation in rustc", + "page": "wg-incr-comp", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": "t-compiler/wg-incr-comp", + "weight": 0 + }, + "discord": [] + }, + "wg-inline-asm": { + "name": "wg-inline-asm", + "kind": "working_group", + "subteam_of": "lang", + "members": [ + { + "name": "Amanieu d'Antras", + "github": "Amanieu", + "github_id": 278509, + "is_lead": true + }, + { + "name": "Josh Triplett", + "github": "joshtriplett", + "github_id": 162737, + "is_lead": true + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-inline-asm", + "members": [ + 278509, + 162737 + ] + } + ] + }, + "website_data": { + "name": "inline-asm project group", + "description": "A working-group project to extend the Rust language to support inline assembly", + "page": "wg-inline-asm", + "email": null, + "repo": "https://github.com/rust-lang/project-inline-asm", + "discord": null, + "zulip_stream": "project-inline-asm", + "weight": 0 + }, + "discord": [] + }, + "wg-leads": { + "name": "wg-leads", + "kind": "working_group", + "subteam_of": null, + "members": [ + { + "name": "Adam C. Foltzer", + "github": "acfoltzer", + "github_id": 205266, + "is_lead": false + }, + { + "name": "Adam Greig", + "github": "adamgreig", + "github_id": 47219, + "is_lead": false + }, + { + "name": "Amanieu d'Antras", + "github": "Amanieu", + "github_id": 278509, + "is_lead": false + }, + { + "name": "Forest Anderson", + "github": "AngelOnFira", + "github_id": 14791619, + "is_lead": false + }, + { + "name": "apiraino", + "github": "apiraino", + "github_id": 6098822, + "is_lead": false + }, + { + "name": "Kyle J Strand", + "github": "BatmanAoD", + "github_id": 2313807, + "is_lead": false + }, + { + "name": "Celina V.", + "github": "celinval", + "github_id": 35149715, + "is_lead": false + }, + { + "name": "Camille Gillot", + "github": "cjgillot", + "github_id": 1822483, + "is_lead": false + }, + { + "name": "Charles Lew", + "github": "crlf0710", + "github_id": 451806, + "is_lead": false + }, + { + "name": "David Wood", + "github": "davidtwco", + "github_id": 1295100, + "is_lead": false + }, + { + "name": "Doc Jones", + "github": "doc-jones", + "github_id": 37349558, + "is_lead": false + }, + { + "name": "Dylan DPC", + "github": "Dylan-DPC", + "github_id": 99973273, + "is_lead": false + }, + { + "name": "Eduard-Mihai Burtescu", + "github": "eddyb", + "github_id": 77424, + "is_lead": false + }, + { + "name": "Emilio Cobos Álvarez", + "github": "emilio", + "github_id": 1323194, + "is_lead": false + }, + { + "name": "Ed Page", + "github": "epage", + "github_id": 60961, + "is_lead": false + }, + { + "name": "Erlend Sogge Heggen", + "github": "erlend-sh", + "github_id": 583842, + "is_lead": false + }, + { + "name": "Esteban Kuber", + "github": "estebank", + "github_id": 1606434, + "is_lead": false + }, + { + "name": "Nick Fitzgerald", + "github": "fitzgen", + "github_id": 74571, + "is_lead": false + }, + { + "name": "Jack Huey", + "github": "jackh726", + "github_id": 31162821, + "is_lead": false + }, + { + "name": "Jorge Aparicio", + "github": "japaric", + "github_id": 5018213, + "is_lead": false + }, + { + "name": "Yuki Okushi", + "github": "JohnTitor", + "github_id": 25030997, + "is_lead": false + }, + { + "name": "Josh Triplett", + "github": "joshtriplett", + "github_id": 162737, + "is_lead": false + }, + { + "name": "Dzmitry Malyshau", + "github": "kvark", + "github_id": 107301, + "is_lead": false + }, + { + "name": "lcnr", + "github": "lcnr", + "github_id": 29864074, + "is_lead": false + }, + { + "name": "Rémy Rakic", + "github": "lqd", + "github_id": 247183, + "is_lead": false + }, + { + "name": "Mara Bos", + "github": "m-ou-se", + "github_id": 783247, + "is_lead": false + }, + { + "name": "Mário Idival", + "github": "marioidival", + "github_id": 1129263, + "is_lead": false + }, + { + "name": "Mark Rousskov", + "github": "Mark-Simulacrum", + "github_id": 5047365, + "is_lead": false + }, + { + "name": "Aleksey Kladov", + "github": "matklad", + "github_id": 1711539, + "is_lead": false + }, + { + "name": "Matthew Jasper", + "github": "matthewjasper", + "github_id": 20113453, + "is_lead": false + }, + { + "name": "Michael Woerister", + "github": "michaelwoerister", + "github_id": 1825894, + "is_lead": false + }, + { + "name": "Simonas Kazlauskas", + "github": "nagisa", + "github_id": 679122, + "is_lead": false + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": false + }, + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": false + }, + { + "name": "Andrey Lesnikov", + "github": "ozkriff", + "github_id": 662976, + "is_lead": false + }, + { + "name": "Felix Klock", + "github": "pnkfelix", + "github_id": 173127, + "is_lead": false + }, + { + "name": "Ralf Jung", + "github": "RalfJung", + "github_id": 330628, + "is_lead": false + }, + { + "name": "Ramon de C Valle", + "github": "rcvalle", + "github_id": 3988004, + "is_lead": false + }, + { + "name": "Ryan Levick", + "github": "rylev", + "github_id": 1327285, + "is_lead": false + }, + { + "name": "Sergey Davidoff", + "github": "Shnatsel", + "github_id": 291257, + "is_lead": false + }, + { + "name": "Santiago Pastorino", + "github": "spastorino", + "github_id": 52642, + "is_lead": false + }, + { + "name": "Tony Arcieri", + "github": "tarcieri", + "github_id": 797, + "is_lead": false + }, + { + "name": "Daniel Egger", + "github": "therealprof", + "github_id": 3321888, + "is_lead": false + }, + { + "name": "Tim Diekmann", + "github": "TimDiekmann", + "github_id": 21277928, + "is_lead": false + }, + { + "name": "Tyler Mandry", + "github": "tmandry", + "github_id": 2280544, + "is_lead": false + }, + { + "name": "Lukas Wirth", + "github": "Veykril", + "github_id": 3757771, + "is_lead": false + }, + { + "name": "Wesley Wiser", + "github": "wesleywiser", + "github_id": 831192, + "is_lead": false + }, + { + "name": "Jubilee", + "github": "workingjubilee", + "github_id": 46493976, + "is_lead": false + }, + { + "name": "Jane Lusby", + "github": "yaahc", + "github_id": 1993852, + "is_lead": false + }, + { + "name": "Yoshua Wuyts", + "github": "yoshuawuyts", + "github_id": 2467194, + "is_lead": false + } + ], + "alumni": [], + "github": null, + "website_data": null, + "discord": [] + }, + "wg-llvm": { + "name": "wg-llvm", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Simonas Kazlauskas", + "github": "nagisa", + "github_id": 679122, + "is_lead": true + }, + { + "name": "Josh Stone", + "github": "cuviper", + "github_id": 36186, + "is_lead": false + }, + { + "name": "Nikita Popov", + "github": "nikic", + "github_id": 216080, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-llvm", + "members": [ + 36186, + 679122, + 216080 + ] + } + ] + }, + "website_data": { + "name": "LLVM working group", + "description": "Working with LLVM upstream to represent Rust in its development", + "page": "wg-llvm", + "email": null, + "repo": "https://rust-lang.github.io/compiler-team/working-groups/llvm/", + "discord": null, + "zulip_stream": "t-compiler/wg-llvm", + "weight": 0 + }, + "discord": [] + }, + "wg-mir-opt": { + "name": "wg-mir-opt", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": true + }, + { + "name": "David Wood", + "github": "davidtwco", + "github_id": 1295100, + "is_lead": false + }, + { + "name": "Eduard-Mihai Burtescu", + "github": "eddyb", + "github_id": 77424, + "is_lead": false + }, + { + "name": "Jakob Degen", + "github": "JakobDegen", + "github_id": 51179609, + "is_lead": false + }, + { + "name": "Santiago Pastorino", + "github": "spastorino", + "github_id": 52642, + "is_lead": false + }, + { + "name": "Mahmut Bulut", + "github": "vertexclique", + "github_id": 578559, + "is_lead": false + }, + { + "name": "Wesley Wiser", + "github": "wesleywiser", + "github_id": 831192, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-mir-opt", + "members": [ + 51179609, + 1295100, + 77424, + 332036, + 52642, + 578559, + 831192 + ] + } + ] + }, + "website_data": { + "name": "MIR optimizations working group", + "description": "Writing MIR optimizations and refactoring the MIR to be more optimizable", + "page": "wg-mir-opt", + "email": null, + "repo": "https://rust-lang.github.io/compiler-team/working-groups/mir-opt/", + "discord": null, + "zulip_stream": "t-compiler/wg-mir-opt", + "weight": 0 + }, + "discord": [] + }, + "wg-parallel-rustc": { + "name": "wg-parallel-rustc", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Camille Gillot", + "github": "cjgillot", + "github_id": 1822483, + "is_lead": true + }, + { + "name": "bjorn3", + "github": "bjorn3", + "github_id": 17426603, + "is_lead": false + }, + { + "name": "Jakub Beránek", + "github": "Kobzol", + "github_id": 4539057, + "is_lead": false + }, + { + "name": "Nicholas Nethercote", + "github": "nnethercote", + "github_id": 1940286, + "is_lead": false + }, + { + "name": "Sparrow Li", + "github": "SparrowLii", + "github_id": 68270294, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Alex Crichton", + "github": "alexcrichton", + "github_id": 64996, + "is_lead": false + }, + { + "name": "Josh Stone", + "github": "cuviper", + "github_id": 36186, + "is_lead": false + }, + { + "name": "Mark Rousskov", + "github": "Mark-Simulacrum", + "github_id": 5047365, + "is_lead": false + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": false + }, + { + "name": "Santiago Pastorino", + "github": "spastorino", + "github_id": 52642, + "is_lead": false + } + ], + "github": null, + "website_data": { + "name": "Parallel rustc working group", + "description": "Making parallel compilation the default for rustc", + "page": "wg-parallel-rustc", + "email": null, + "repo": "https://rust-lang.github.io/compiler-team/working-groups/parallel-rustc/", + "discord": null, + "zulip_stream": "t-compiler/wg-parallel-rustc", + "weight": 0 + }, + "discord": [] + }, + "wg-parselib": { + "name": "wg-parselib", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Aleksey Kladov", + "github": "matklad", + "github_id": 1711539, + "is_lead": true + } + ], + "alumni": [], + "github": null, + "website_data": { + "name": "Parselib working group", + "description": "Sharing the parser between rustc and rust-analyzer", + "page": "wg-parselib", + "email": null, + "repo": "https://rust-lang.github.io/compiler-team/working-groups/parselib/", + "discord": null, + "zulip_stream": "t-compiler/wg-parselib", + "weight": 0 + }, + "discord": [] + }, + "wg-pgo": { + "name": "wg-pgo", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Michael Woerister", + "github": "michaelwoerister", + "github_id": 1825894, + "is_lead": true + } + ], + "alumni": [], + "github": null, + "website_data": { + "name": "Profile-guided optimization working group", + "description": "Implementing profile-guided optimization for rustc", + "page": "wg-pgo", + "email": null, + "repo": "https://rust-lang.github.io/compiler-team/working-groups/pgo/", + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-polonius": { + "name": "wg-polonius", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Rémy Rakic", + "github": "lqd", + "github_id": 247183, + "is_lead": true + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": true + }, + { + "name": "Amanda Stjerna", + "github": "amandasystems", + "github_id": 102855, + "is_lead": false + }, + { + "name": "Dylan MacKenzie", + "github": "ecstatic-morse", + "github_id": 29463364, + "is_lead": false + }, + { + "name": "Matthew Jasper", + "github": "matthewjasper", + "github_id": 20113453, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-polonius", + "members": [ + 102855, + 29463364, + 247183, + 20113453, + 155238 + ] + } + ] + }, + "website_data": { + "name": "Polonius working group", + "description": "Working on an experimental new borrow-checker implementation", + "page": "wg-polonius", + "email": null, + "repo": "https://rust-lang.github.io/compiler-team/working-groups/polonius/", + "discord": null, + "zulip_stream": "t-compiler/wg-polonius", + "weight": 0 + }, + "discord": [] + }, + "wg-polymorphization": { + "name": "wg-polymorphization", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "David Wood", + "github": "davidtwco", + "github_id": 1295100, + "is_lead": true + }, + { + "name": "Eduard-Mihai Burtescu", + "github": "eddyb", + "github_id": 77424, + "is_lead": false + }, + { + "name": "lcnr", + "github": "lcnr", + "github_id": 29864074, + "is_lead": false + } + ], + "alumni": [], + "github": null, + "website_data": { + "name": "Polymorphization working group", + "description": "Implementing polymorphization to reduce unnecessary monomorphisation in rustc", + "page": "wg-polymorphization", + "email": null, + "repo": "https://rust-lang.github.io/compiler-team/working-groups/polymorphization/", + "discord": null, + "zulip_stream": "t-compiler/wg-polymorphization", + "weight": 0 + }, + "discord": [] + }, + "wg-prioritization": { + "name": "wg-prioritization", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "apiraino", + "github": "apiraino", + "github_id": 6098822, + "is_lead": true + }, + { + "name": "Wesley Wiser", + "github": "wesleywiser", + "github_id": 831192, + "is_lead": true + }, + { + "name": "amit", + "github": "am-1t", + "github_id": 28247396, + "is_lead": false + }, + { + "name": "Bawer Dagdeviren", + "github": "bawerd", + "github_id": 625483, + "is_lead": false + }, + { + "name": "Noah Lev", + "github": "camelid", + "github_id": 37223377, + "is_lead": false + }, + { + "name": "DJ Carpenter", + "github": "djcarpe", + "github_id": 59489977, + "is_lead": false + }, + { + "name": "Dylan DPC", + "github": "Dylan-DPC", + "github_id": 99973273, + "is_lead": false + }, + { + "name": "Fredrik Østrem", + "github": "frxstrem", + "github_id": 1686349, + "is_lead": false + }, + { + "name": "Hameer Abbasi", + "github": "hameerabbasi", + "github_id": 2190658, + "is_lead": false + }, + { + "name": "Hirochika Matsumoto", + "github": "hkmatsumoto", + "github_id": 57856193, + "is_lead": false + }, + { + "name": "inquisitivecrystal", + "github": "inquisitivecrystal", + "github_id": 22333129, + "is_lead": false + }, + { + "name": "James Gill", + "github": "JamesPatrickGill", + "github_id": 44863195, + "is_lead": false + }, + { + "name": "Jonathan Chasteen", + "github": "jechasteen", + "github_id": 13788397, + "is_lead": false + }, + { + "name": "Yuki Okushi", + "github": "JohnTitor", + "github_id": 25030997, + "is_lead": false + }, + { + "name": "lcnr", + "github": "lcnr", + "github_id": 29864074, + "is_lead": false + }, + { + "name": "Mason Stallmo", + "github": "mstallmo", + "github_id": 6796542, + "is_lead": false + }, + { + "name": "Jeremy Lempereur", + "github": "o0Ignition0o", + "github_id": 9465678, + "is_lead": false + }, + { + "name": "Felix Klock", + "github": "pnkfelix", + "github_id": 173127, + "is_lead": false + }, + { + "name": "Stu", + "github": "Stupremee", + "github_id": 39732259, + "is_lead": false + }, + { + "name": "Takayuki Maeda", + "github": "TaKO8Ki", + "github_id": 41065217, + "is_lead": false + }, + { + "name": "Yohei Tamura", + "github": "tamuhey", + "github_id": 24998666, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Mazdak Farrokhzad", + "github": "Centril", + "github_id": 855702, + "is_lead": false + }, + { + "name": "Joshua Nelson", + "github": "jyn514", + "github_id": 23638587, + "is_lead": false + }, + { + "name": "Léo Lanteri Thauvin", + "github": "LeSeulArtichaut", + "github_id": 38361244, + "is_lead": false + }, + { + "name": "Who? Me?!", + "github": "mark-i-m", + "github_id": 8827840, + "is_lead": false + }, + { + "name": "Santiago Pastorino", + "github": "spastorino", + "github_id": 52642, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-prioritization", + "members": [ + 99973273, + 44863195, + 25030997, + 39732259, + 41065217, + 28247396, + 6098822, + 625483, + 37223377, + 59489977, + 1686349, + 2190658, + 57856193, + 22333129, + 13788397, + 29864074, + 6796542, + 9465678, + 173127, + 24998666, + 831192 + ] + } + ] + }, + "website_data": { + "name": "Prioritization working group", + "description": "Triaging bugs, mainly deciding if bugs are critical (potential release blockers) or not", + "page": "wg-prioritization", + "email": null, + "repo": "https://rust-lang.github.io/compiler-team/working-groups/prioritization/", + "discord": null, + "zulip_stream": "t-compiler/wg-prioritization", + "weight": 0 + }, + "discord": [] + }, + "wg-rfc-2229": { + "name": "wg-rfc-2229", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Matthew Jasper", + "github": "matthewjasper", + "github_id": 20113453, + "is_lead": true + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": true + }, + { + "name": "Aman Arora", + "github": "arora-aman", + "github_id": 4193035, + "is_lead": false + }, + { + "name": "Archer Zhang", + "github": "Azhng", + "github_id": 9267198, + "is_lead": false + }, + { + "name": "ChrisPardy", + "github": "ChrisPardy", + "github_id": 25291724, + "is_lead": false + }, + { + "name": "Jennifer Wills", + "github": "jenniferwills", + "github_id": 22324472, + "is_lead": false + }, + { + "name": "logmosier", + "github": "logmosier", + "github_id": 10948303, + "is_lead": false + }, + { + "name": "Dhruv Jauhar", + "github": "null-sleep", + "github_id": 13277988, + "is_lead": false + }, + { + "name": "Roxane", + "github": "roxelo", + "github_id": 12419401, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-rfc-2229", + "members": [ + 9267198, + 25291724, + 4193035, + 22324472, + 10948303, + 20113453, + 155238, + 13277988, + 12419401 + ] + } + ] + }, + "website_data": { + "name": "RFC 2229 working group", + "description": "Improving the behavior of closure-capture, and improving the documentation on closures", + "page": "wg-rfc-2229", + "email": null, + "repo": "https://rust-lang.github.io/compiler-team/working-groups/rfc-2229/", + "discord": null, + "zulip_stream": "t-compiler/wg-rfc-2229", + "weight": 0 + }, + "discord": [] + }, + "wg-rls-2": { + "name": "wg-rls-2", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Lukas Wirth", + "github": "Veykril", + "github_id": 3757771, + "is_lead": true + }, + { + "name": "Florian Diebold", + "github": "flodiebold", + "github_id": 906069, + "is_lead": false + }, + { + "name": "Jonas Schievink", + "github": "jonas-schievink", + "github_id": 1786438, + "is_lead": false + }, + { + "name": "Laurențiu Nicola", + "github": "lnicola", + "github_id": 308347, + "is_lead": false + }, + { + "name": "Aleksey Kladov", + "github": "matklad", + "github_id": 1711539, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-analyzer", + "name": "wg-rls-2", + "members": [ + 3757771, + 906069, + 1786438, + 308347, + 1711539 + ] + }, + { + "org": "rust-lang", + "name": "wg-rls-2", + "members": [ + 3757771, + 906069, + 1786438, + 308347, + 1711539 + ] + } + ] + }, + "website_data": { + "name": "RLS 2.0 working group", + "description": "Experimenting with a new compiler architecture tailored for IDEs", + "page": "wg-rls-2", + "email": null, + "repo": "https://rust-lang.github.io/compiler-team/working-groups/rls-2.0/", + "discord": null, + "zulip_stream": "t-compiler/rust-analyzer", + "weight": 0 + }, + "discord": [] + }, + "wg-rls-2-triage": { + "name": "wg-rls-2-triage", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "bjorn3", + "github": "bjorn3", + "github_id": 17426603, + "is_lead": false + }, + { + "name": "Edwin Cheng", + "github": "edwin0cheng", + "github_id": 11014119, + "is_lead": false + }, + { + "name": "Ryo Yoshida", + "github": "lowr", + "github_id": 24381114, + "is_lead": false + }, + { + "name": "Kirill Bulatov", + "github": "SomeoneToIgnore", + "github_id": 2690773, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-analyzer", + "name": "wg-rls-2-triage", + "members": [ + 2690773, + 17426603, + 11014119, + 24381114 + ] + }, + { + "org": "rust-lang", + "name": "wg-rls-2-triage", + "members": [ + 2690773, + 17426603, + 11014119, + 24381114 + ] + } + ] + }, + "website_data": null, + "discord": [] + }, + "wg-rust-by-example": { + "name": "wg-rust-by-example", + "kind": "working_group", + "subteam_of": null, + "members": [ + { + "name": "Mário Idival", + "github": "marioidival", + "github_id": 1129263, + "is_lead": true + } + ], + "alumni": [ + { + "name": "Steve Klabnik", + "github": "steveklabnik", + "github_id": 27786, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-rust-by-example", + "members": [ + 1129263 + ] + } + ] + }, + "website_data": { + "name": "Rust by Example working group", + "description": "Maintaining and updating the official Rust by Example book", + "page": "wg-rust-by-example", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-rustc-dev-guide": { + "name": "wg-rustc-dev-guide", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Yuki Okushi", + "github": "JohnTitor", + "github_id": 25030997, + "is_lead": true + }, + { + "name": "Santiago Pastorino", + "github": "spastorino", + "github_id": 52642, + "is_lead": true + }, + { + "name": "Noah Lev", + "github": "camelid", + "github_id": 37223377, + "is_lead": false + }, + { + "name": "Iñaki Garay", + "github": "igaray", + "github_id": 167193, + "is_lead": false + }, + { + "name": "Tshepang Mbambo", + "github": "tshepang", + "github_id": 588486, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Amanjeev Sethi", + "github": "amanjeev", + "github_id": 160476, + "is_lead": false + }, + { + "name": "Chris Simpkins", + "github": "chrissimpkins", + "github_id": 4249591, + "is_lead": false + }, + { + "name": "Joshua Nelson", + "github": "jyn514", + "github_id": 23638587, + "is_lead": false + }, + { + "name": "Léo Lanteri Thauvin", + "github": "LeSeulArtichaut", + "github_id": 38361244, + "is_lead": false + }, + { + "name": "Who? Me?!", + "github": "mark-i-m", + "github_id": 8827840, + "is_lead": false + }, + { + "name": "Paul Daniel Faria", + "github": "Nashenas88", + "github_id": 1673130, + "is_lead": false + }, + { + "name": "pierwill", + "github": "pierwill", + "github_id": 19642016, + "is_lead": false + }, + { + "name": "Ryan Levick", + "github": "rylev", + "github_id": 1327285, + "is_lead": false + }, + { + "name": "Togi Sergey", + "github": "togiberlin", + "github_id": 13764830, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-rustc-dev-guide", + "members": [ + 25030997, + 37223377, + 167193, + 52642, + 588486 + ] + } + ] + }, + "website_data": { + "name": "Rustc Dev Guide working group", + "description": "Making the compiler easier to learn by maintaining and improving the Rustc Dev Guide", + "page": "wg-rustc-dev-guide", + "email": null, + "repo": "https://rust-lang.github.io/compiler-team/working-groups/rustc-dev-guide/", + "discord": null, + "zulip_stream": "t-compiler/wg-rustc-dev-guide", + "weight": 0 + }, + "discord": [] + }, + "wg-rustc-reading-club": { + "name": "wg-rustc-reading-club", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Doc Jones", + "github": "doc-jones", + "github_id": 37349558, + "is_lead": true + }, + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": true + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-rustc-reading-club", + "members": [ + 37349558, + 155238 + ] + } + ] + }, + "website_data": { + "name": "Rust Code Reading Club working group", + "description": "Helping new and experienced contributors learn more about rustc", + "page": "wg-rustc-reading-club", + "email": null, + "repo": "https://rust-lang.github.io/rustc-reading-club/", + "discord": null, + "zulip_stream": "rustc-reading-club", + "weight": 0 + }, + "discord": [] + }, + "wg-rustfix": { + "name": "wg-rustfix", + "kind": "working_group", + "subteam_of": "devtools", + "members": [ + { + "name": "Esteban Kuber", + "github": "estebank", + "github_id": 1606434, + "is_lead": false + }, + { + "name": "Pascal Hertleif", + "github": "killercup", + "github_id": 20063, + "is_lead": false + }, + { + "name": "Manish Goregaokar", + "github": "Manishearth", + "github_id": 1617736, + "is_lead": false + }, + { + "name": "Oliver Scherer", + "github": "oli-obk", + "github_id": 332036, + "is_lead": false + }, + { + "name": "Philipp Hansch", + "github": "phansch", + "github_id": 2042399, + "is_lead": false + }, + { + "name": "Pietro Albini", + "github": "pietroalbini", + "github_id": 2299951, + "is_lead": false + } + ], + "alumni": [], + "github": null, + "website_data": { + "name": "Rustfix working group", + "description": "Developing cargo-fix and serving as a point of contact for other teams", + "page": "wg-rustfix", + "email": null, + "repo": null, + "discord": { + "channel": "#wg-rustfix", + "url": "https://discord.gg/e6Q3cvu" + }, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "wg-safe-transmute": { + "name": "wg-safe-transmute", + "kind": "working_group", + "subteam_of": "lang", + "members": [ + { + "name": "Josh Triplett", + "github": "joshtriplett", + "github_id": 162737, + "is_lead": true + }, + { + "name": "Ryan Levick", + "github": "rylev", + "github_id": 1327285, + "is_lead": true + }, + { + "name": "Jack Wrenn", + "github": "jswrenn", + "github_id": 3820879, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-safe-transmute", + "members": [ + 162737, + 3820879, + 1327285 + ] + } + ] + }, + "website_data": { + "name": "safe-transmute project group", + "description": "A working-group project to extend the Rust language to support safe transmute between types", + "page": "wg-safe-transmute", + "email": null, + "repo": "https://github.com/rust-lang/project-safe-transmute", + "discord": null, + "zulip_stream": "project-safe-transmute", + "weight": 0 + }, + "discord": [] + }, + "wg-secure-code": { + "name": "wg-secure-code", + "kind": "working_group", + "subteam_of": null, + "members": [ + { + "name": "Sergey Davidoff", + "github": "Shnatsel", + "github_id": 291257, + "is_lead": true + }, + { + "name": "Tony Arcieri", + "github": "tarcieri", + "github_id": 797, + "is_lead": true + }, + { + "name": "Alex Gaynor", + "github": "alex", + "github_id": 772, + "is_lead": false + }, + { + "name": "Alexis Mousset", + "github": "amousset", + "github_id": 329388, + "is_lead": false + }, + { + "name": "pinkforest", + "github": "pinkforest", + "github_id": 36498018, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Daniel Henry-Mantilla", + "github": "danielhenrymantilla", + "github_id": 9920355, + "is_lead": false + }, + { + "name": "Stuart Small", + "github": "stusmall", + "github_id": 1697444, + "is_lead": false + }, + { + "name": "Joel Wejdenstål", + "github": "xacrimon", + "github_id": 21025159, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-secure-code", + "members": [ + 291257, + 772, + 329388, + 36498018, + 797 + ] + } + ] + }, + "website_data": { + "name": "Secure Code working group", + "description": "Making it easy to write secure code in Rust", + "page": "wg-secure-code", + "email": null, + "repo": "https://github.com/rust-secure-code/wg", + "discord": null, + "zulip_stream": "wg-secure-code", + "weight": 0 + }, + "discord": [] + }, + "wg-security-response": { + "name": "wg-security-response", + "kind": "working_group", + "subteam_of": null, + "members": [ + { + "name": "Josh Stone", + "github": "cuviper", + "github_id": 36186, + "is_lead": false + }, + { + "name": "Pietro Albini", + "github": "pietroalbini", + "github_id": 2299951, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": false + }, + { + "name": "Steve Klabnik", + "github": "steveklabnik", + "github_id": 27786, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "security", + "members": [ + 36186, + 2299951 + ] + } + ] + }, + "website_data": { + "name": "Security Response WG", + "description": "Triaging and responding to incoming vulnerability reports", + "page": "wg-security-response", + "email": "security@rust-lang.org", + "repo": "https://github.com/rust-lang/wg-security-response", + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [ + { + "name": "security", + "members": [ + 296309029947441155, + 443825361256448003 + ], + "color": "#e91e63" + } + ] + }, + "wg-self-profile": { + "name": "wg-self-profile", + "kind": "working_group", + "subteam_of": "compiler", + "members": [ + { + "name": "Michael Woerister", + "github": "michaelwoerister", + "github_id": 1825894, + "is_lead": true + }, + { + "name": "Wesley Wiser", + "github": "wesleywiser", + "github_id": 831192, + "is_lead": true + } + ], + "alumni": [], + "github": null, + "website_data": { + "name": "Self-profile working group", + "description": "Improving the -Z self-profile feature of the Rust compiler", + "page": "wg-self-profile", + "email": null, + "repo": "https://rust-lang.github.io/compiler-team/working-groups/self-profile/", + "discord": null, + "zulip_stream": "t-compiler/wg-self-profile", + "weight": 0 + }, + "discord": [] + }, + "wg-triage": { + "name": "wg-triage", + "kind": "working_group", + "subteam_of": "release", + "members": [ + { + "name": "Dylan DPC", + "github": "Dylan-DPC", + "github_id": 99973273, + "is_lead": true + }, + { + "name": "Alex Macleod", + "github": "Alexendoo", + "github_id": 1830331, + "is_lead": false + }, + { + "name": "Alice Cecile", + "github": "alice-i-cecile", + "github_id": 3579909, + "is_lead": false + }, + { + "name": "Ben Striegel", + "github": "bstrie", + "github_id": 865233, + "is_lead": false + }, + { + "name": "Noah Lev", + "github": "camelid", + "github_id": 37223377, + "is_lead": false + }, + { + "name": "Charles Lew", + "github": "crlf0710", + "github_id": 451806, + "is_lead": false + }, + { + "name": "Edmilson Ferreira da Silva", + "github": "edmilsonefs", + "github_id": 498938, + "is_lead": false + }, + { + "name": "Joel Parmer", + "github": "joelpalmer", + "github_id": 8049061, + "is_lead": false + }, + { + "name": "John Simon", + "github": "JohnCSimon", + "github_id": 1977159, + "is_lead": false + }, + { + "name": "Yuki Okushi", + "github": "JohnTitor", + "github_id": 25030997, + "is_lead": false + }, + { + "name": "Owen Salter", + "github": "Muirrum", + "github_id": 8702646, + "is_lead": false + } + ], + "alumni": [], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-triage", + "members": [ + 1830331, + 99973273, + 1977159, + 25030997, + 8702646, + 3579909, + 865233, + 37223377, + 451806, + 498938, + 8049061 + ] + } + ] + }, + "website_data": { + "name": "Triage working group", + "description": "Triaging repositories under the rust-lang organisation", + "page": "wg-triage", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": "t-release/triage", + "weight": 0 + }, + "discord": [] + }, + "wg-unsafe-code-guidelines": { + "name": "wg-unsafe-code-guidelines", + "kind": "working_group", + "subteam_of": "lang", + "members": [ + { + "name": "Niko Matsakis", + "github": "nikomatsakis", + "github_id": 155238, + "is_lead": true + }, + { + "name": "Ralf Jung", + "github": "RalfJung", + "github_id": 330628, + "is_lead": true + }, + { + "name": "Christopher Durham", + "github": "CAD97", + "github_id": 5992217, + "is_lead": false + }, + { + "name": "comex", + "github": "comex", + "github_id": 47517, + "is_lead": false + }, + { + "name": "Mario Carneiro", + "github": "digama0", + "github_id": 868588, + "is_lead": false + }, + { + "name": "Jakob Degen", + "github": "JakobDegen", + "github_id": 51179609, + "is_lead": false + } + ], + "alumni": [ + { + "name": "Diane Hosfelt", + "github": "avadacatavra", + "github_id": 11877868, + "is_lead": false + } + ], + "github": { + "teams": [ + { + "org": "rust-lang", + "name": "wg-unsafe-code-guidelines", + "members": [ + 5992217, + 51179609, + 330628, + 47517, + 868588, + 155238 + ] + } + ] + }, + "website_data": { + "name": "Unsafe Code Guidelines (UCG) working group", + "description": "Working out the \"Unsafe Code Guidelines\", which define what unsafe code can and cannot do", + "page": "wg-unsafe-code-guidelines", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": "t-lang/wg-unsafe-code-guidelines", + "weight": 0 + }, + "discord": [] + }, + "wg-wasm": { + "name": "wg-wasm", + "kind": "working_group", + "subteam_of": null, + "members": [ + { + "name": "Nick Fitzgerald", + "github": "fitzgen", + "github_id": 74571, + "is_lead": true + } + ], + "alumni": [ + { + "name": "Ashley Williams", + "github": "ashleygwilliams", + "github_id": 1163554, + "is_lead": false + } + ], + "github": null, + "website_data": { + "name": "WebAssembly (WASM) working group", + "description": "Improving on the end-to-end experience of embedding Rust code in JS libraries and apps via WebAssembly", + "page": "wasm", + "email": null, + "repo": null, + "discord": null, + "zulip_stream": null, + "weight": 0 + }, + "discord": [] + }, + "windows": { + "name": "windows", + "kind": "marker_team", + "subteam_of": null, + "members": [ + { + "name": "Albert Larsan", + "github": "albertlarsan68", + "github_id": 74931857, + "is_lead": false + }, + { + "name": "Arlo Siemsen", + "github": "arlosi", + "github_id": 704597, + "is_lead": false + }, + { + "name": "Chris Denton", + "github": "ChrisDenton", + "github_id": 4459874, + "is_lead": false + }, + { + "name": "Daniel Frampton", + "github": "danielframpton", + "github_id": 15899604, + "is_lead": false + }, + { + "name": "Gabriel Dos Reis", + "github": "gdr-at-ms", + "github_id": 11031650, + "is_lead": false + }, + { + "name": "Kenny Kerr", + "github": "kennykerr", + "github_id": 9845234, + "is_lead": false + }, + { + "name": "Luqman Aden", + "github": "luqmana", + "github_id": 287063, + "is_lead": false + }, + { + "name": "Jason Shirk", + "github": "lzybkr", + "github_id": 2148248, + "is_lead": false + }, + { + "name": "Nicolas", + "github": "nico-abram", + "github_id": 24706838, + "is_lead": false + }, + { + "name": "Peter Atashian", + "github": "retep998", + "github_id": 666308, + "is_lead": false + }, + { + "name": "Ryan Levick", + "github": "rylev", + "github_id": 1327285, + "is_lead": false + }, + { + "name": "Arlie Davis", + "github": "sivadeilra", + "github_id": 4743776, + "is_lead": false + }, + { + "name": "Wesley Wiser", + "github": "wesleywiser", + "github_id": 831192, + "is_lead": false + } + ], + "alumni": [], + "github": null, + "website_data": null, + "discord": [] + } +} \ No newline at end of file diff --git a/tests/server_test/shortcut.rs b/tests/server_test/shortcut.rs new file mode 100644 index 00000000..6e3c5d4a --- /dev/null +++ b/tests/server_test/shortcut.rs @@ -0,0 +1,101 @@ +use crate::server_test::TestPrBuilder; +use super::run_test; +use crate::server_test::ServerTestSetup; +use triagebot::github::{GithubClient, Repository}; +use triagebot::github::{Issue, Label}; + +async fn prepare_repo_for_shortcut(setup: &ServerTestSetup, initial_label: &str) -> Issue { + setup.config("[shortcut]").await; + // Set up labels that all shortcut tests need. + for label in ["S-waiting-on-review", "S-waiting-on-author", "S-blocked"] { + if !setup.repo.has_label(&setup.gh, label).await.unwrap() { + setup + .repo + .create_label(&setup.gh, label, "d3dddd", "") + .await + .unwrap(); + } + } + let pr = TestPrBuilder::new("shortcut-test", &setup.repo.default_branch) + .create(&setup.gh, &setup.repo).await; + pr.add_labels( + &setup.gh, + vec![Label { + name: initial_label.into(), + }], + ) + .await + .unwrap(); + pr +} + +async fn wait_for_labels(gh: &GithubClient, repo: &Repository, pr: u64, labels: &[&str]) { + eprintln!("waiting for labels to update"); + for _ in 0..5 { + let pr = repo.get_pr(gh, pr).await.unwrap(); + let current_labels = pr.labels(); + eprintln!("current_labels={current_labels:?}"); + if labels + .iter() + .all(|expected| current_labels.iter().any(|l| l.name == *expected)) + && labels.len() == current_labels.len() + { + return; + } + tokio::time::sleep(std::time::Duration::new(5, 0)).await; + } + panic!("labels did not update to expected {labels:?}"); +} + +async fn shortcut_test( + setup: ServerTestSetup, + initial_label: &str, + comment: &str, + expected_label: &str, +) { + let pr = prepare_repo_for_shortcut(&setup, initial_label).await; + let ctx = setup.launch_triagebot_live(); + let gh = ctx.gh.as_ref().unwrap(); + let repo = ctx.repo.as_ref().unwrap(); + pr.post_comment(gh, comment).await.unwrap(); + wait_for_labels(gh, repo, pr.number, &[expected_label]).await; +} + +#[test] +fn author() { + run_test("shortcut/author", |setup| async move { + shortcut_test( + setup, + "S-waiting-on-review", + "@rustbot author", + "S-waiting-on-author", + ) + .await; + }); +} + +#[test] +fn ready() { + run_test("shortcut/ready", |setup| async move { + shortcut_test( + setup, + "S-waiting-on-author", + "@rustbot ready", + "S-waiting-on-review", + ) + .await; + }); +} + +#[test] +fn blocked() { + run_test("shortcut/blocked", |setup| async move { + shortcut_test( + setup, + "S-waiting-on-author", + "@rustbot blocked", + "S-blocked", + ) + .await; + }); +} diff --git a/tests/server_test/shortcut/author/00-webhook-issue104_comment_created.json b/tests/server_test/shortcut/author/00-webhook-issue104_comment_created.json new file mode 100644 index 00000000..c5457c64 --- /dev/null +++ b/tests/server_test/shortcut/author/00-webhook-issue104_comment_created.json @@ -0,0 +1,249 @@ +{ + "kind": "Webhook", + "webhook_event": "issue_comment", + "payload": { + "action": "created", + "comment": { + "author_association": "OWNER", + "body": "@rustbot author", + "created_at": "2023-03-08T00:08:48Z", + "html_url": "https://github.com/ehuss/triagebot-test/pull/104#issuecomment-1459060804", + "id": 1459060804, + "issue_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/104", + "node_id": "IC_kwDOHkK3Xc5W94BE", + "performed_via_github_app": null, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments/1459060804/reactions" + }, + "updated_at": "2023-03-08T00:08:48Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments/1459060804", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "issue": { + "active_lock_reason": null, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "body": "This is a test PR.", + "closed_at": null, + "comments": 1, + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/104/comments", + "created_at": "2023-03-08T00:08:43Z", + "draft": false, + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/104/events", + "html_url": "https://github.com/ehuss/triagebot-test/pull/104", + "id": 1614409551, + "labels": [ + { + "color": "BCA930", + "default": false, + "description": "", + "id": 5014682663, + "name": "S-waiting-on-review", + "node_id": "LA_kwDOHkK3Xc8AAAABKuX8Jw", + "url": "https://api.github.com/repos/ehuss/triagebot-test/labels/S-waiting-on-review" + } + ], + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/104/labels{/name}", + "locked": false, + "milestone": null, + "node_id": "PR_kwDOHkK3Xc5LhtHN", + "number": 104, + "performed_via_github_app": null, + "pull_request": { + "diff_url": "https://github.com/ehuss/triagebot-test/pull/104.diff", + "html_url": "https://github.com/ehuss/triagebot-test/pull/104", + "merged_at": null, + "patch_url": "https://github.com/ehuss/triagebot-test/pull/104.patch", + "url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/104" + }, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/104/reactions" + }, + "repository_url": "https://api.github.com/repos/ehuss/triagebot-test", + "state": "open", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/104/timeline", + "title": "Test PR", + "updated_at": "2023-03-08T00:08:48Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/104", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T00:08:43Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 21, + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/shortcut/author/01-GET-ehuss_triagebot-test_main_triagebot_toml.json b/tests/server_test/shortcut/author/01-GET-ehuss_triagebot-test_main_triagebot_toml.json new file mode 100644 index 00000000..5b755678 --- /dev/null +++ b/tests/server_test/shortcut/author/01-GET-ehuss_triagebot-test_main_triagebot_toml.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/ehuss/triagebot-test/main/triagebot.toml", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": "[shortcut]" +} \ No newline at end of file diff --git a/tests/server_test/shortcut/author/02-DELETE-repos_ehuss_triagebot-test_issues_104_labels_S-waiting-on-review.json b/tests/server_test/shortcut/author/02-DELETE-repos_ehuss_triagebot-test_issues_104_labels_S-waiting-on-review.json new file mode 100644 index 00000000..b42083be --- /dev/null +++ b/tests/server_test/shortcut/author/02-DELETE-repos_ehuss_triagebot-test_issues_104_labels_S-waiting-on-review.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "DELETE", + "path": "/repos/ehuss/triagebot-test/issues/104/labels/S-waiting-on-review", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": [] +} \ No newline at end of file diff --git a/tests/server_test/shortcut/author/03-GET-repos_ehuss_triagebot-test_labels_S-waiting-on-author.json b/tests/server_test/shortcut/author/03-GET-repos_ehuss_triagebot-test_labels_S-waiting-on-author.json new file mode 100644 index 00000000..7cdb4985 --- /dev/null +++ b/tests/server_test/shortcut/author/03-GET-repos_ehuss_triagebot-test_labels_S-waiting-on-author.json @@ -0,0 +1,17 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/ehuss/triagebot-test/labels/S-waiting-on-author", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "color": "d4c5f9", + "default": false, + "description": "", + "id": 4569402041, + "name": "S-waiting-on-author", + "node_id": "LA_kwDOHkK3Xc8AAAABEFuKuQ", + "url": "https://api.github.com/repos/ehuss/triagebot-test/labels/S-waiting-on-author" + } +} \ No newline at end of file diff --git a/tests/server_test/shortcut/author/04-POST-repos_ehuss_triagebot-test_issues_104_labels.json b/tests/server_test/shortcut/author/04-POST-repos_ehuss_triagebot-test_issues_104_labels.json new file mode 100644 index 00000000..b9418c8d --- /dev/null +++ b/tests/server_test/shortcut/author/04-POST-repos_ehuss_triagebot-test_issues_104_labels.json @@ -0,0 +1,19 @@ +{ + "kind": "Request", + "method": "POST", + "path": "/repos/ehuss/triagebot-test/issues/104/labels", + "query": null, + "request_body": "{\"labels\":[\"S-waiting-on-author\"]}", + "response_code": 200, + "response_body": [ + { + "color": "d4c5f9", + "default": false, + "description": "", + "id": 4569402041, + "name": "S-waiting-on-author", + "node_id": "LA_kwDOHkK3Xc8AAAABEFuKuQ", + "url": "https://api.github.com/repos/ehuss/triagebot-test/labels/S-waiting-on-author" + } + ] +} \ No newline at end of file diff --git a/tests/server_test/shortcut/author/05-GET-v1_teams_json.json b/tests/server_test/shortcut/author/05-GET-v1_teams_json.json new file mode 100644 index 00000000..25f6ff7d --- /dev/null +++ b/tests/server_test/shortcut/author/05-GET-v1_teams_json.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/v1/teams.json", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": null +} \ No newline at end of file diff --git a/tests/server_test/shortcut/author/06-GET-v1_teams_json.json b/tests/server_test/shortcut/author/06-GET-v1_teams_json.json new file mode 100644 index 00000000..25f6ff7d --- /dev/null +++ b/tests/server_test/shortcut/author/06-GET-v1_teams_json.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/v1/teams.json", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": null +} \ No newline at end of file diff --git a/tests/server_test/shortcut/author/07-webhook-pr104_unlabeled.json b/tests/server_test/shortcut/author/07-webhook-pr104_unlabeled.json new file mode 100644 index 00000000..f6e57462 --- /dev/null +++ b/tests/server_test/shortcut/author/07-webhook-pr104_unlabeled.json @@ -0,0 +1,501 @@ +{ + "kind": "Webhook", + "webhook_event": "pull_request", + "payload": { + "action": "unlabeled", + "label": { + "color": "BCA930", + "default": false, + "description": "", + "id": 5014682663, + "name": "S-waiting-on-review", + "node_id": "LA_kwDOHkK3Xc8AAAABKuX8Jw", + "url": "https://api.github.com/repos/ehuss/triagebot-test/labels/S-waiting-on-review" + }, + "number": 104, + "pull_request": { + "_links": { + "comments": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/issues/104/comments" + }, + "commits": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/104/commits" + }, + "html": { + "href": "https://github.com/ehuss/triagebot-test/pull/104" + }, + "issue": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/issues/104" + }, + "review_comment": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/comments{/number}" + }, + "review_comments": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/104/comments" + }, + "self": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/104" + }, + "statuses": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/statuses/15805ca09211eb8308fa61ba0d18037f730614c8" + } + }, + "active_lock_reason": null, + "additions": 1, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "auto_merge": null, + "base": { + "label": "ehuss:main", + "ref": "main", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T00:08:43Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 21, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "30c0ddf10a3a88ea2208181670bca52a7d05eeaa", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "body": "This is a test PR.", + "changed_files": 1, + "closed_at": null, + "comments": 1, + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/104/comments", + "commits": 1, + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/104/commits", + "created_at": "2023-03-08T00:08:43Z", + "deletions": 0, + "diff_url": "https://github.com/ehuss/triagebot-test/pull/104.diff", + "draft": false, + "head": { + "label": "ehuss:shortcut-test", + "ref": "shortcut-test", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T00:08:43Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 21, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "15805ca09211eb8308fa61ba0d18037f730614c8", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "html_url": "https://github.com/ehuss/triagebot-test/pull/104", + "id": 1267126733, + "issue_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/104", + "labels": [], + "locked": false, + "maintainer_can_modify": false, + "merge_commit_sha": "dc01638299f63f93363fed2e2c5a556c879f51c1", + "mergeable": true, + "mergeable_state": "clean", + "merged": false, + "merged_at": null, + "merged_by": null, + "milestone": null, + "node_id": "PR_kwDOHkK3Xc5LhtHN", + "number": 104, + "patch_url": "https://github.com/ehuss/triagebot-test/pull/104.patch", + "rebaseable": true, + "requested_reviewers": [], + "requested_teams": [], + "review_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/comments{/number}", + "review_comments": 0, + "review_comments_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/104/comments", + "state": "open", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/15805ca09211eb8308fa61ba0d18037f730614c8", + "title": "Test PR", + "updated_at": "2023-03-08T00:08:50Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/104", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T00:08:43Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 21, + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/shortcut/author/08-webhook-pr104_labeled.json b/tests/server_test/shortcut/author/08-webhook-pr104_labeled.json new file mode 100644 index 00000000..f014a81a --- /dev/null +++ b/tests/server_test/shortcut/author/08-webhook-pr104_labeled.json @@ -0,0 +1,511 @@ +{ + "kind": "Webhook", + "webhook_event": "pull_request", + "payload": { + "action": "labeled", + "label": { + "color": "d4c5f9", + "default": false, + "description": "", + "id": 4569402041, + "name": "S-waiting-on-author", + "node_id": "LA_kwDOHkK3Xc8AAAABEFuKuQ", + "url": "https://api.github.com/repos/ehuss/triagebot-test/labels/S-waiting-on-author" + }, + "number": 104, + "pull_request": { + "_links": { + "comments": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/issues/104/comments" + }, + "commits": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/104/commits" + }, + "html": { + "href": "https://github.com/ehuss/triagebot-test/pull/104" + }, + "issue": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/issues/104" + }, + "review_comment": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/comments{/number}" + }, + "review_comments": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/104/comments" + }, + "self": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/104" + }, + "statuses": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/statuses/15805ca09211eb8308fa61ba0d18037f730614c8" + } + }, + "active_lock_reason": null, + "additions": 1, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "auto_merge": null, + "base": { + "label": "ehuss:main", + "ref": "main", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T00:08:43Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 21, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "30c0ddf10a3a88ea2208181670bca52a7d05eeaa", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "body": "This is a test PR.", + "changed_files": 1, + "closed_at": null, + "comments": 1, + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/104/comments", + "commits": 1, + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/104/commits", + "created_at": "2023-03-08T00:08:43Z", + "deletions": 0, + "diff_url": "https://github.com/ehuss/triagebot-test/pull/104.diff", + "draft": false, + "head": { + "label": "ehuss:shortcut-test", + "ref": "shortcut-test", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T00:08:43Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 21, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "15805ca09211eb8308fa61ba0d18037f730614c8", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "html_url": "https://github.com/ehuss/triagebot-test/pull/104", + "id": 1267126733, + "issue_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/104", + "labels": [ + { + "color": "d4c5f9", + "default": false, + "description": "", + "id": 4569402041, + "name": "S-waiting-on-author", + "node_id": "LA_kwDOHkK3Xc8AAAABEFuKuQ", + "url": "https://api.github.com/repos/ehuss/triagebot-test/labels/S-waiting-on-author" + } + ], + "locked": false, + "maintainer_can_modify": false, + "merge_commit_sha": "dc01638299f63f93363fed2e2c5a556c879f51c1", + "mergeable": true, + "mergeable_state": "clean", + "merged": false, + "merged_at": null, + "merged_by": null, + "milestone": null, + "node_id": "PR_kwDOHkK3Xc5LhtHN", + "number": 104, + "patch_url": "https://github.com/ehuss/triagebot-test/pull/104.patch", + "rebaseable": true, + "requested_reviewers": [], + "requested_teams": [], + "review_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/comments{/number}", + "review_comments": 0, + "review_comments_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/104/comments", + "state": "open", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/15805ca09211eb8308fa61ba0d18037f730614c8", + "title": "Test PR", + "updated_at": "2023-03-08T00:08:51Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/104", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T00:08:43Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 21, + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/shortcut/blocked/00-webhook-issue106_comment_created.json b/tests/server_test/shortcut/blocked/00-webhook-issue106_comment_created.json new file mode 100644 index 00000000..4115cddc --- /dev/null +++ b/tests/server_test/shortcut/blocked/00-webhook-issue106_comment_created.json @@ -0,0 +1,249 @@ +{ + "kind": "Webhook", + "webhook_event": "issue_comment", + "payload": { + "action": "created", + "comment": { + "author_association": "OWNER", + "body": "@rustbot blocked", + "created_at": "2023-03-08T01:51:42Z", + "html_url": "https://github.com/ehuss/triagebot-test/pull/106#issuecomment-1459143736", + "id": 1459143736, + "issue_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/106", + "node_id": "IC_kwDOHkK3Xc5W-MQ4", + "performed_via_github_app": null, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments/1459143736/reactions" + }, + "updated_at": "2023-03-08T01:51:42Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments/1459143736", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "issue": { + "active_lock_reason": null, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "body": "This is a test PR.", + "closed_at": null, + "comments": 1, + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/106/comments", + "created_at": "2023-03-08T01:51:37Z", + "draft": false, + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/106/events", + "html_url": "https://github.com/ehuss/triagebot-test/pull/106", + "id": 1614500632, + "labels": [ + { + "color": "d4c5f9", + "default": false, + "description": "", + "id": 4569402041, + "name": "S-waiting-on-author", + "node_id": "LA_kwDOHkK3Xc8AAAABEFuKuQ", + "url": "https://api.github.com/repos/ehuss/triagebot-test/labels/S-waiting-on-author" + } + ], + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/106/labels{/name}", + "locked": false, + "milestone": null, + "node_id": "PR_kwDOHkK3Xc5Lh_5-", + "number": 106, + "performed_via_github_app": null, + "pull_request": { + "diff_url": "https://github.com/ehuss/triagebot-test/pull/106.diff", + "html_url": "https://github.com/ehuss/triagebot-test/pull/106", + "merged_at": null, + "patch_url": "https://github.com/ehuss/triagebot-test/pull/106.patch", + "url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/106" + }, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/106/reactions" + }, + "repository_url": "https://api.github.com/repos/ehuss/triagebot-test", + "state": "open", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/106/timeline", + "title": "Test PR", + "updated_at": "2023-03-08T01:51:42Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/106", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T01:51:37Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/shortcut/blocked/01-GET-ehuss_triagebot-test_main_triagebot_toml.json b/tests/server_test/shortcut/blocked/01-GET-ehuss_triagebot-test_main_triagebot_toml.json new file mode 100644 index 00000000..5b755678 --- /dev/null +++ b/tests/server_test/shortcut/blocked/01-GET-ehuss_triagebot-test_main_triagebot_toml.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/ehuss/triagebot-test/main/triagebot.toml", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": "[shortcut]" +} \ No newline at end of file diff --git a/tests/server_test/shortcut/blocked/02-DELETE-repos_ehuss_triagebot-test_issues_106_labels_S-waiting-on-author.json b/tests/server_test/shortcut/blocked/02-DELETE-repos_ehuss_triagebot-test_issues_106_labels_S-waiting-on-author.json new file mode 100644 index 00000000..6ee09d4e --- /dev/null +++ b/tests/server_test/shortcut/blocked/02-DELETE-repos_ehuss_triagebot-test_issues_106_labels_S-waiting-on-author.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "DELETE", + "path": "/repos/ehuss/triagebot-test/issues/106/labels/S-waiting-on-author", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": [] +} \ No newline at end of file diff --git a/tests/server_test/shortcut/blocked/03-GET-repos_ehuss_triagebot-test_labels_S-blocked.json b/tests/server_test/shortcut/blocked/03-GET-repos_ehuss_triagebot-test_labels_S-blocked.json new file mode 100644 index 00000000..fb1b67b3 --- /dev/null +++ b/tests/server_test/shortcut/blocked/03-GET-repos_ehuss_triagebot-test_labels_S-blocked.json @@ -0,0 +1,17 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/ehuss/triagebot-test/labels/S-blocked", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "color": "F311AF", + "default": false, + "description": "", + "id": 5018014919, + "name": "S-blocked", + "node_id": "LA_kwDOHkK3Xc8AAAABKxjUxw", + "url": "https://api.github.com/repos/ehuss/triagebot-test/labels/S-blocked" + } +} \ No newline at end of file diff --git a/tests/server_test/shortcut/blocked/04-POST-repos_ehuss_triagebot-test_issues_106_labels.json b/tests/server_test/shortcut/blocked/04-POST-repos_ehuss_triagebot-test_issues_106_labels.json new file mode 100644 index 00000000..d6f78c7f --- /dev/null +++ b/tests/server_test/shortcut/blocked/04-POST-repos_ehuss_triagebot-test_issues_106_labels.json @@ -0,0 +1,19 @@ +{ + "kind": "Request", + "method": "POST", + "path": "/repos/ehuss/triagebot-test/issues/106/labels", + "query": null, + "request_body": "{\"labels\":[\"S-blocked\"]}", + "response_code": 200, + "response_body": [ + { + "color": "F311AF", + "default": false, + "description": "", + "id": 5018014919, + "name": "S-blocked", + "node_id": "LA_kwDOHkK3Xc8AAAABKxjUxw", + "url": "https://api.github.com/repos/ehuss/triagebot-test/labels/S-blocked" + } + ] +} \ No newline at end of file diff --git a/tests/server_test/shortcut/blocked/05-GET-v1_teams_json.json b/tests/server_test/shortcut/blocked/05-GET-v1_teams_json.json new file mode 100644 index 00000000..25f6ff7d --- /dev/null +++ b/tests/server_test/shortcut/blocked/05-GET-v1_teams_json.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/v1/teams.json", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": null +} \ No newline at end of file diff --git a/tests/server_test/shortcut/blocked/06-GET-v1_teams_json.json b/tests/server_test/shortcut/blocked/06-GET-v1_teams_json.json new file mode 100644 index 00000000..25f6ff7d --- /dev/null +++ b/tests/server_test/shortcut/blocked/06-GET-v1_teams_json.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/v1/teams.json", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": null +} \ No newline at end of file diff --git a/tests/server_test/shortcut/blocked/07-webhook-pr106_unlabeled.json b/tests/server_test/shortcut/blocked/07-webhook-pr106_unlabeled.json new file mode 100644 index 00000000..fcffbb7e --- /dev/null +++ b/tests/server_test/shortcut/blocked/07-webhook-pr106_unlabeled.json @@ -0,0 +1,501 @@ +{ + "kind": "Webhook", + "webhook_event": "pull_request", + "payload": { + "action": "unlabeled", + "label": { + "color": "d4c5f9", + "default": false, + "description": "", + "id": 4569402041, + "name": "S-waiting-on-author", + "node_id": "LA_kwDOHkK3Xc8AAAABEFuKuQ", + "url": "https://api.github.com/repos/ehuss/triagebot-test/labels/S-waiting-on-author" + }, + "number": 106, + "pull_request": { + "_links": { + "comments": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/issues/106/comments" + }, + "commits": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/106/commits" + }, + "html": { + "href": "https://github.com/ehuss/triagebot-test/pull/106" + }, + "issue": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/issues/106" + }, + "review_comment": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/comments{/number}" + }, + "review_comments": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/106/comments" + }, + "self": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/106" + }, + "statuses": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/statuses/7b952c92414800caecdeea4262471ee5494d1193" + } + }, + "active_lock_reason": null, + "additions": 1, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "auto_merge": null, + "base": { + "label": "ehuss:main", + "ref": "main", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T01:51:37Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "bd0459104c93c5bbfd609989f292172d378520a6", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "body": "This is a test PR.", + "changed_files": 1, + "closed_at": null, + "comments": 1, + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/106/comments", + "commits": 1, + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/106/commits", + "created_at": "2023-03-08T01:51:37Z", + "deletions": 0, + "diff_url": "https://github.com/ehuss/triagebot-test/pull/106.diff", + "draft": false, + "head": { + "label": "ehuss:shortcut-test", + "ref": "shortcut-test", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T01:51:37Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "7b952c92414800caecdeea4262471ee5494d1193", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "html_url": "https://github.com/ehuss/triagebot-test/pull/106", + "id": 1267203710, + "issue_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/106", + "labels": [], + "locked": false, + "maintainer_can_modify": false, + "merge_commit_sha": "2ba8e5f32e90523f7ba9524f995207639224b75c", + "mergeable": true, + "mergeable_state": "clean", + "merged": false, + "merged_at": null, + "merged_by": null, + "milestone": null, + "node_id": "PR_kwDOHkK3Xc5Lh_5-", + "number": 106, + "patch_url": "https://github.com/ehuss/triagebot-test/pull/106.patch", + "rebaseable": true, + "requested_reviewers": [], + "requested_teams": [], + "review_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/comments{/number}", + "review_comments": 0, + "review_comments_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/106/comments", + "state": "open", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/7b952c92414800caecdeea4262471ee5494d1193", + "title": "Test PR", + "updated_at": "2023-03-08T01:51:43Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/106", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T01:51:37Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/shortcut/blocked/08-webhook-pr106_labeled.json b/tests/server_test/shortcut/blocked/08-webhook-pr106_labeled.json new file mode 100644 index 00000000..a4db7dd7 --- /dev/null +++ b/tests/server_test/shortcut/blocked/08-webhook-pr106_labeled.json @@ -0,0 +1,511 @@ +{ + "kind": "Webhook", + "webhook_event": "pull_request", + "payload": { + "action": "labeled", + "label": { + "color": "F311AF", + "default": false, + "description": "", + "id": 5018014919, + "name": "S-blocked", + "node_id": "LA_kwDOHkK3Xc8AAAABKxjUxw", + "url": "https://api.github.com/repos/ehuss/triagebot-test/labels/S-blocked" + }, + "number": 106, + "pull_request": { + "_links": { + "comments": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/issues/106/comments" + }, + "commits": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/106/commits" + }, + "html": { + "href": "https://github.com/ehuss/triagebot-test/pull/106" + }, + "issue": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/issues/106" + }, + "review_comment": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/comments{/number}" + }, + "review_comments": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/106/comments" + }, + "self": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/pulls/106" + }, + "statuses": { + "href": "https://api.github.com/repos/ehuss/triagebot-test/statuses/7b952c92414800caecdeea4262471ee5494d1193" + } + }, + "active_lock_reason": null, + "additions": 1, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "auto_merge": null, + "base": { + "label": "ehuss:main", + "ref": "main", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T01:51:37Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "bd0459104c93c5bbfd609989f292172d378520a6", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "body": "This is a test PR.", + "changed_files": 1, + "closed_at": null, + "comments": 1, + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/106/comments", + "commits": 1, + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/106/commits", + "created_at": "2023-03-08T01:51:37Z", + "deletions": 0, + "diff_url": "https://github.com/ehuss/triagebot-test/pull/106.diff", + "draft": false, + "head": { + "label": "ehuss:shortcut-test", + "ref": "shortcut-test", + "repo": { + "allow_auto_merge": false, + "allow_forking": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_squash_merge": true, + "allow_update_branch": false, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "delete_branch_on_merge": false, + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE", + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T01:51:37Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "use_squash_pr_title_as_default": false, + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sha": "7b952c92414800caecdeea4262471ee5494d1193", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "html_url": "https://github.com/ehuss/triagebot-test/pull/106", + "id": 1267203710, + "issue_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/106", + "labels": [ + { + "color": "F311AF", + "default": false, + "description": "", + "id": 5018014919, + "name": "S-blocked", + "node_id": "LA_kwDOHkK3Xc8AAAABKxjUxw", + "url": "https://api.github.com/repos/ehuss/triagebot-test/labels/S-blocked" + } + ], + "locked": false, + "maintainer_can_modify": false, + "merge_commit_sha": "2ba8e5f32e90523f7ba9524f995207639224b75c", + "mergeable": true, + "mergeable_state": "clean", + "merged": false, + "merged_at": null, + "merged_by": null, + "milestone": null, + "node_id": "PR_kwDOHkK3Xc5Lh_5-", + "number": 106, + "patch_url": "https://github.com/ehuss/triagebot-test/pull/106.patch", + "rebaseable": true, + "requested_reviewers": [], + "requested_teams": [], + "review_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/comments{/number}", + "review_comments": 0, + "review_comments_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/106/comments", + "state": "open", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/7b952c92414800caecdeea4262471ee5494d1193", + "title": "Test PR", + "updated_at": "2023-03-08T01:51:44Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/106", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T01:51:37Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/shortcut/ready/00-webhook-issue105_comment_created.json b/tests/server_test/shortcut/ready/00-webhook-issue105_comment_created.json new file mode 100644 index 00000000..9d671778 --- /dev/null +++ b/tests/server_test/shortcut/ready/00-webhook-issue105_comment_created.json @@ -0,0 +1,249 @@ +{ + "kind": "Webhook", + "webhook_event": "issue_comment", + "payload": { + "action": "created", + "comment": { + "author_association": "OWNER", + "body": "@rustbot ready", + "created_at": "2023-03-08T01:50:54Z", + "html_url": "https://github.com/ehuss/triagebot-test/pull/105#issuecomment-1459143229", + "id": 1459143229, + "issue_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/105", + "node_id": "IC_kwDOHkK3Xc5W-MI9", + "performed_via_github_app": null, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments/1459143229/reactions" + }, + "updated_at": "2023-03-08T01:50:54Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments/1459143229", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "issue": { + "active_lock_reason": null, + "assignee": null, + "assignees": [], + "author_association": "OWNER", + "body": "This is a test PR.", + "closed_at": null, + "comments": 1, + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/105/comments", + "created_at": "2023-03-08T01:50:48Z", + "draft": false, + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/105/events", + "html_url": "https://github.com/ehuss/triagebot-test/pull/105", + "id": 1614500054, + "labels": [ + { + "color": "d4c5f9", + "default": false, + "description": "", + "id": 4569402041, + "name": "S-waiting-on-author", + "node_id": "LA_kwDOHkK3Xc8AAAABEFuKuQ", + "url": "https://api.github.com/repos/ehuss/triagebot-test/labels/S-waiting-on-author" + } + ], + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/105/labels{/name}", + "locked": false, + "milestone": null, + "node_id": "PR_kwDOHkK3Xc5Lh_yQ", + "number": 105, + "performed_via_github_app": null, + "pull_request": { + "diff_url": "https://github.com/ehuss/triagebot-test/pull/105.diff", + "html_url": "https://github.com/ehuss/triagebot-test/pull/105", + "merged_at": null, + "patch_url": "https://github.com/ehuss/triagebot-test/pull/105.patch", + "url": "https://api.github.com/repos/ehuss/triagebot-test/pulls/105" + }, + "reactions": { + "+1": 0, + "-1": 0, + "confused": 0, + "eyes": 0, + "heart": 0, + "hooray": 0, + "laugh": 0, + "rocket": 0, + "total_count": 0, + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/105/reactions" + }, + "repository_url": "https://api.github.com/repos/ehuss/triagebot-test", + "state": "open", + "state_reason": null, + "timeline_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/105/timeline", + "title": "Test PR", + "updated_at": "2023-03-08T01:50:54Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test/issues/105", + "user": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + }, + "repository": { + "allow_forking": true, + "archive_url": "https://api.github.com/repos/ehuss/triagebot-test/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/ehuss/triagebot-test/assignees{/user}", + "blobs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/ehuss/triagebot-test/branches{/branch}", + "clone_url": "https://github.com/ehuss/triagebot-test.git", + "collaborators_url": "https://api.github.com/repos/ehuss/triagebot-test/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/ehuss/triagebot-test/comments{/number}", + "commits_url": "https://api.github.com/repos/ehuss/triagebot-test/commits{/sha}", + "compare_url": "https://api.github.com/repos/ehuss/triagebot-test/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/ehuss/triagebot-test/contents/{+path}", + "contributors_url": "https://api.github.com/repos/ehuss/triagebot-test/contributors", + "created_at": "2022-06-26T21:31:31Z", + "default_branch": "main", + "deployments_url": "https://api.github.com/repos/ehuss/triagebot-test/deployments", + "description": "Triagebot testing", + "disabled": false, + "downloads_url": "https://api.github.com/repos/ehuss/triagebot-test/downloads", + "events_url": "https://api.github.com/repos/ehuss/triagebot-test/events", + "fork": false, + "forks": 1, + "forks_count": 1, + "forks_url": "https://api.github.com/repos/ehuss/triagebot-test/forks", + "full_name": "ehuss/triagebot-test", + "git_commits_url": "https://api.github.com/repos/ehuss/triagebot-test/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/ehuss/triagebot-test/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/ehuss/triagebot-test/git/tags{/sha}", + "git_url": "git://github.com/ehuss/triagebot-test.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": true, + "homepage": null, + "hooks_url": "https://api.github.com/repos/ehuss/triagebot-test/hooks", + "html_url": "https://github.com/ehuss/triagebot-test", + "id": 507688797, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/ehuss/triagebot-test/issues/events{/number}", + "issues_url": "https://api.github.com/repos/ehuss/triagebot-test/issues{/number}", + "keys_url": "https://api.github.com/repos/ehuss/triagebot-test/keys{/key_id}", + "labels_url": "https://api.github.com/repos/ehuss/triagebot-test/labels{/name}", + "language": null, + "languages_url": "https://api.github.com/repos/ehuss/triagebot-test/languages", + "license": null, + "merges_url": "https://api.github.com/repos/ehuss/triagebot-test/merges", + "milestones_url": "https://api.github.com/repos/ehuss/triagebot-test/milestones{/number}", + "mirror_url": null, + "name": "triagebot-test", + "node_id": "R_kgDOHkK3XQ", + "notifications_url": "https://api.github.com/repos/ehuss/triagebot-test/notifications{?since,all,participating}", + "open_issues": 8, + "open_issues_count": 8, + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + }, + "private": false, + "pulls_url": "https://api.github.com/repos/ehuss/triagebot-test/pulls{/number}", + "pushed_at": "2023-03-08T01:50:48Z", + "releases_url": "https://api.github.com/repos/ehuss/triagebot-test/releases{/id}", + "size": 22, + "ssh_url": "git@github.com:ehuss/triagebot-test.git", + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/ehuss/triagebot-test/stargazers", + "statuses_url": "https://api.github.com/repos/ehuss/triagebot-test/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/ehuss/triagebot-test/subscribers", + "subscription_url": "https://api.github.com/repos/ehuss/triagebot-test/subscription", + "svn_url": "https://github.com/ehuss/triagebot-test", + "tags_url": "https://api.github.com/repos/ehuss/triagebot-test/tags", + "teams_url": "https://api.github.com/repos/ehuss/triagebot-test/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/ehuss/triagebot-test/git/trees{/sha}", + "updated_at": "2022-06-26T21:31:31Z", + "url": "https://api.github.com/repos/ehuss/triagebot-test", + "visibility": "public", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/43198?v=4", + "events_url": "https://api.github.com/users/ehuss/events{/privacy}", + "followers_url": "https://api.github.com/users/ehuss/followers", + "following_url": "https://api.github.com/users/ehuss/following{/other_user}", + "gists_url": "https://api.github.com/users/ehuss/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/ehuss", + "id": 43198, + "login": "ehuss", + "node_id": "MDQ6VXNlcjQzMTk4", + "organizations_url": "https://api.github.com/users/ehuss/orgs", + "received_events_url": "https://api.github.com/users/ehuss/received_events", + "repos_url": "https://api.github.com/users/ehuss/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/ehuss/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ehuss/subscriptions", + "type": "User", + "url": "https://api.github.com/users/ehuss" + } + } +} \ No newline at end of file diff --git a/tests/server_test/shortcut/ready/01-GET-ehuss_triagebot-test_main_triagebot_toml.json b/tests/server_test/shortcut/ready/01-GET-ehuss_triagebot-test_main_triagebot_toml.json new file mode 100644 index 00000000..5b755678 --- /dev/null +++ b/tests/server_test/shortcut/ready/01-GET-ehuss_triagebot-test_main_triagebot_toml.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/ehuss/triagebot-test/main/triagebot.toml", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": "[shortcut]" +} \ No newline at end of file diff --git a/tests/server_test/shortcut/ready/02-DELETE-repos_ehuss_triagebot-test_issues_105_labels_S-waiting-on-author.json b/tests/server_test/shortcut/ready/02-DELETE-repos_ehuss_triagebot-test_issues_105_labels_S-waiting-on-author.json new file mode 100644 index 00000000..f20bfbd0 --- /dev/null +++ b/tests/server_test/shortcut/ready/02-DELETE-repos_ehuss_triagebot-test_issues_105_labels_S-waiting-on-author.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "DELETE", + "path": "/repos/ehuss/triagebot-test/issues/105/labels/S-waiting-on-author", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": [] +} \ No newline at end of file diff --git a/tests/server_test/shortcut/ready/03-GET-repos_ehuss_triagebot-test_labels_S-waiting-on-review.json b/tests/server_test/shortcut/ready/03-GET-repos_ehuss_triagebot-test_labels_S-waiting-on-review.json new file mode 100644 index 00000000..4f7a84b7 --- /dev/null +++ b/tests/server_test/shortcut/ready/03-GET-repos_ehuss_triagebot-test_labels_S-waiting-on-review.json @@ -0,0 +1,17 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/repos/ehuss/triagebot-test/labels/S-waiting-on-review", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": { + "color": "BCA930", + "default": false, + "description": "", + "id": 5014682663, + "name": "S-waiting-on-review", + "node_id": "LA_kwDOHkK3Xc8AAAABKuX8Jw", + "url": "https://api.github.com/repos/ehuss/triagebot-test/labels/S-waiting-on-review" + } +} \ No newline at end of file diff --git a/tests/server_test/shortcut/ready/04-POST-repos_ehuss_triagebot-test_issues_105_labels.json b/tests/server_test/shortcut/ready/04-POST-repos_ehuss_triagebot-test_issues_105_labels.json new file mode 100644 index 00000000..18278c00 --- /dev/null +++ b/tests/server_test/shortcut/ready/04-POST-repos_ehuss_triagebot-test_issues_105_labels.json @@ -0,0 +1,19 @@ +{ + "kind": "Request", + "method": "POST", + "path": "/repos/ehuss/triagebot-test/issues/105/labels", + "query": null, + "request_body": "{\"labels\":[\"S-waiting-on-review\"]}", + "response_code": 200, + "response_body": [ + { + "color": "BCA930", + "default": false, + "description": "", + "id": 5014682663, + "name": "S-waiting-on-review", + "node_id": "LA_kwDOHkK3Xc8AAAABKuX8Jw", + "url": "https://api.github.com/repos/ehuss/triagebot-test/labels/S-waiting-on-review" + } + ] +} \ No newline at end of file diff --git a/tests/server_test/shortcut/ready/05-GET-v1_teams_json.json b/tests/server_test/shortcut/ready/05-GET-v1_teams_json.json new file mode 100644 index 00000000..25f6ff7d --- /dev/null +++ b/tests/server_test/shortcut/ready/05-GET-v1_teams_json.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/v1/teams.json", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": null +} \ No newline at end of file diff --git a/tests/server_test/shortcut/ready/06-GET-v1_teams_json.json b/tests/server_test/shortcut/ready/06-GET-v1_teams_json.json new file mode 100644 index 00000000..25f6ff7d --- /dev/null +++ b/tests/server_test/shortcut/ready/06-GET-v1_teams_json.json @@ -0,0 +1,9 @@ +{ + "kind": "Request", + "method": "GET", + "path": "/v1/teams.json", + "query": null, + "request_body": "", + "response_code": 200, + "response_body": null +} \ No newline at end of file diff --git a/tests/testsuite.rs b/tests/testsuite.rs new file mode 100644 index 00000000..f5058d71 --- /dev/null +++ b/tests/testsuite.rs @@ -0,0 +1,398 @@ +//! Triagebot integration testsuite. +//! +//! There are three types of tests here: +//! +//! * `github_client` — This tests the behavior `GithubClient`. +//! * `server_test` — This launches the `triagebot` executable, injects +//! webhook events into it, and validates the behavior. +//! * `db` — This directly tests the database API. +//! +//! See the individual modules for an introduction to writing these tests. +//! +//! The tests generally work by launching an HTTP server and intercepting HTTP +//! requests that would normally go to external sites like +//! https://api.github.com. + +mod db; +mod github_client; +mod server_test; + +use chrono::DateTime; +use std::collections::HashMap; +use std::io::{BufRead, BufReader, Read, Write}; +use std::net::TcpStream; +use std::net::{SocketAddr, TcpListener}; +use std::path::{Path, PathBuf}; +use std::sync::atomic::{AtomicBool, AtomicU32, Ordering}; +use std::sync::mpsc; +use std::sync::Mutex; +use triagebot::test_record::{self, Activity}; +use url::Url; + +pub fn test_dir() -> PathBuf { + thread_local! { + static TEST_ID: Mutex> = Mutex::new(None); + } + static NEXT_ID: AtomicU32 = AtomicU32::new(0); + let path_from_id = |id| { + let tmp_dir = Path::new(env!("CARGO_TARGET_TMPDIR")).join("testsuite"); + tmp_dir.join(format!("t{id}")) + }; + + let this_id = TEST_ID.with(|n| { + let mut v = n.lock().unwrap(); + match *v { + None => { + let test_id = NEXT_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + let test_dir = path_from_id(test_id); + if test_dir.exists() { + std::fs::remove_dir_all(&test_dir).unwrap(); + } + std::fs::create_dir_all(&test_dir).unwrap(); + *v = Some(test_id); + test_id + } + Some(id) => id, + } + }); + path_from_id(this_id) +} + +/// A request received on the HTTP server. +#[derive(Clone, Debug)] +pub struct Request { + /// The path of the request, such as `repos/rust-lang/rust/labels`. + pub path: String, + /// The HTTP method. + pub method: String, + /// The query components of the URL (the stuff after `?`). + pub query: Option, + /// HTTP headers. + pub headers: HashMap, + /// The body of the HTTP request (usually a JSON blob). + pub body: Vec, +} + +/// The response the HTTP server should send to the client. +pub struct Response { + pub code: u16, + pub headers: Vec, + pub body: Vec, +} + +/// A primitive HTTP server. +pub struct HttpServer { + listener: TcpListener, + /// A sequence of activities that the server should expect, and the + /// responses it should give. + activities: Vec, + /// Which activity in `activities` is currently being processed. + current: usize, + /// Channel for sending webhook events to the main thread, which will send + /// to the triagebot process. + hook_transmit: mpsc::Sender, +} + +/// A reference on how to connect to the test HTTP server. +pub struct HttpServerHandle { + pub addr: SocketAddr, + /// Channel for receiving webhook events to inject into triagebot. + pub hook_recv: mpsc::Receiver, +} + +impl Drop for HttpServerHandle { + fn drop(&mut self) { + if let Ok(mut stream) = TcpStream::connect(self.addr) { + // shut down the server + let _ = stream.write_all(b"STOP"); + let _ = stream.flush(); + } + } +} + +/// Enables logging if `TRIAGEBOT_TEST_LOG` is set. This can help with +/// debugging a test. +pub fn maybe_enable_logging() { + const LOG_VAR: &str = "TRIAGEBOT_TEST_LOG"; + use std::sync::Once; + static DO_INIT: Once = Once::new(); + if std::env::var_os(LOG_VAR).is_some() { + DO_INIT.call_once(|| { + dotenv::dotenv().ok(); + tracing_subscriber::fmt::Subscriber::builder() + .with_env_filter(tracing_subscriber::EnvFilter::from_env(LOG_VAR)) + .with_ansi(std::env::var_os("DISABLE_COLOR").is_none()) + .try_init() + .unwrap(); + }); + } +} + +/// Makes sure recording is only being done for one test (recording multiple +/// tests isn't supported). +pub fn assert_single_record() { + static RECORDING: AtomicBool = AtomicBool::new(false); + if test_record::is_recording() { + if RECORDING.swap(true, Ordering::SeqCst) { + panic!( + "More than one test appears to be recording.\n\ + TRIAGEBOT_TEST_RECORD only supports recording one test at a time.\n\ + Make sure to pass the exact name of the test to `cargo test` with the \ + `--exact` flag to run only one test." + ); + } + } +} + +/// Loads all JSON [`Activity`] blobs from a directory. +pub fn load_activities(test_dir: &str, test_path: &str) -> Vec { + let mut activity_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + activity_path.push(test_dir); + activity_path.push(test_path); + let mut activity_paths: Vec<_> = std::fs::read_dir(&activity_path) + .map_err(|e| { + format!( + "failed to read test activity directory {activity_path:?}: {e}\n\ + Be sure to set the environment variable TRIAGEBOT_TEST_RECORD to the \ + path to record the initial test data against the live GitHub site.\n\ + See the test docs in testsuite.rs for more." + ) + }) + .unwrap() + .filter_map(|entry| entry.ok()) + .filter(|entry| entry.path().extension().and_then(|p| p.to_str()) == Some("json")) + .map(|entry| entry.path()) + .collect(); + if activity_paths.is_empty() { + panic!("expected at least one activity in {activity_path:?}"); + } + activity_paths.sort(); + activity_paths + .into_iter() + .map(|path| { + let contents = std::fs::read_to_string(path).unwrap(); + let mut activity = serde_json::from_str(&contents).unwrap(); + if let Activity::Request { + path, + response_body, + .. + } = &mut activity + { + if path == "/v1/teams.json" { + let mut teams_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + teams_path.push("tests/server_test/shared/teams.json"); + let body = std::fs::read_to_string(teams_path).unwrap(); + let body = serde_json::from_str(&body).unwrap(); + *response_body = body; + } + } + activity + }) + .collect() +} + +impl HttpServer { + pub fn new(activities: Vec) -> HttpServerHandle { + let (hook_transmit, hook_recv) = mpsc::channel(); + let listener = TcpListener::bind("127.0.0.1:0").unwrap(); + let addr = listener.local_addr().unwrap(); + let mut server = HttpServer { + listener, + activities, + current: 0, + hook_transmit, + }; + std::thread::spawn(move || server.start()); + HttpServerHandle { addr, hook_recv } + } + + fn start(&mut self) { + if let Some(activity @ Activity::Webhook { .. }) = self.activities.get(0) { + self.hook_transmit.send(activity.clone()).unwrap(); + self.current += 1; + } + let mut line = String::new(); + 'server: loop { + let (socket, _) = self.listener.accept().unwrap(); + let mut buf = BufReader::new(socket); + line.clear(); + if buf.read_line(&mut line).unwrap() == 0 { + // Connection terminated. + eprintln!("unexpected client drop"); + continue; + } + // Read the "GET path HTTP/1.1" line. + let mut parts = line.split_ascii_whitespace(); + let method = parts.next().unwrap().to_ascii_uppercase(); + if method == "STOP" { + // Shutdown the server. + return; + } + let path = parts.next().unwrap(); + // The host here doesn't matter, we're just interested in parsing + // the query string. + let url = Url::parse(&format!("https://api.github.com{path}")).unwrap(); + + let mut headers = HashMap::new(); + let mut content_len = None; + loop { + line.clear(); + if buf.read_line(&mut line).unwrap() == 0 { + continue 'server; + } + if line == "\r\n" { + // End of headers. + line.clear(); + break; + } + let (name, value) = line.split_once(':').unwrap(); + let name = name.trim().to_ascii_lowercase(); + let value = value.trim().to_string(); + match name.as_str() { + "content-length" => content_len = Some(value.parse::().unwrap()), + _ => {} + } + headers.insert(name, value); + } + let mut body = vec![0u8; content_len.unwrap_or(0) as usize]; + buf.read_exact(&mut body).unwrap(); + + let path = url.path().to_string(); + let query = url.query().map(|s| s.to_string()); + eprintln!("got request {method} {path}"); + let request = Request { + path, + method, + query, + headers, + body, + }; + let response = self.process_request(request); + + let buf = buf.get_mut(); + write!(buf, "HTTP/1.1 {}\r\n", response.code).unwrap(); + write!(buf, "Content-Length: {}\r\n", response.body.len()).unwrap(); + write!(buf, "Connection: close\r\n").unwrap(); + for header in response.headers { + write!(buf, "{}\r\n", header).unwrap(); + } + write!(buf, "\r\n").unwrap(); + buf.write_all(&response.body).unwrap(); + buf.flush().unwrap(); + self.next_activity(); + } + } + + fn next_activity(&mut self) { + loop { + self.current += 1; + match self.activities.get(self.current) { + Some(activity @ Activity::Webhook { .. }) => { + self.hook_transmit.send(activity.clone()).unwrap(); + } + Some(_) => break, + None => { + self.hook_transmit.send(Activity::Finished).unwrap(); + break; + } + } + } + } + + fn process_request(&self, request: Request) -> Response { + let Some(activity) = self.activities.get(self.current) else { + let msg = format!("error: not enough activities\n\ + Make sure the activity log is complete.\n\ + Request was {request:?}\n"); + self.report_err(&msg); + return Response { + code: 500, + headers: Vec::new(), + body: msg.into(), + }; + }; + match activity { + Activity::Webhook { .. } => { + panic!("unexpected webhook") + } + Activity::Request { + method, + path, + query, + request_body, + response_code, + response_body, + } => { + if method != &request.method || path != &request.path { + return self.report_err(&format!( + "expected next request to be {method} {path},\n\ + got {} {}", + request.method, request.path + )); + } + if query != &request.query { + return self.report_err(&format!( + "query string does not match\n\ + expected: {query:?}\n\ + got: {:?}\n", + request.query + )); + } + if request_body.as_bytes() != request.body { + return self.report_err(&format!( + "expected next request {method} {path} to have body:\n\ + {request_body}\n\ + \n\ + got:\n\ + {}", + String::from_utf8_lossy(&request.body) + )); + } + let body = match response_body { + // We overload the meaning of a string to be a raw string. + // I don't think GitHub's API ever returns a string as a response. + serde_json::Value::String(s) => s.as_bytes().to_vec(), + _ => serde_json::to_vec(response_body).unwrap(), + }; + return Response { + code: *response_code, + headers: Vec::new(), + body, + }; + } + Activity::Error { .. } | Activity::Finished => { + panic!("unexpected activity: {activity:?}"); + } + } + } + + fn report_err(&self, message: &str) -> Response { + eprintln!("error: {message}"); + self.hook_transmit + .send(Activity::Error { + message: message.to_string(), + }) + .unwrap(); + Response { + code: 500, + headers: Vec::new(), + body: Vec::from(message.as_bytes()), + } + } +} + +/// Helper for comparing datetimes. +/// +/// This helps ignore sub-second differences (which can happen when +/// round-tripping through a database). +pub fn assert_datetime_approx_equal(a: &DateTime, b: &DateTime) +where + T: chrono::TimeZone, + U: chrono::TimeZone, + ::Offset: std::fmt::Display, + ::Offset: std::fmt::Display, +{ + if a.timestamp() != b.timestamp() { + panic!("datetime differs {a} != {b}"); + } +}