Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:apollographql/router
Browse files Browse the repository at this point in the history
  • Loading branch information
bnjjj committed May 21, 2024
2 parents 2bb67a0 + 8b22c40 commit f4f0ca7
Show file tree
Hide file tree
Showing 60 changed files with 6,348 additions and 556 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
**/target/
.cargo_check

# snapshot testing with the 'insta' crate
*.pending-snap

# These are backup files generated by rustfmt
**/*.rs.bk

Expand Down
28 changes: 25 additions & 3 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ dependencies = [

[[package]]
name = "apollo-federation"
version = "1.47.0-rc.0"
version = "1.47.0"
dependencies = [
"apollo-compiler",
"derive_more",
Expand Down Expand Up @@ -324,6 +324,7 @@ dependencies = [
"jsonwebtoken",
"lazy_static",
"libc",
"libtest-mimic",
"linkme",
"lru",
"maplit",
Expand Down Expand Up @@ -2515,6 +2516,15 @@ dependencies = [
"windows-sys 0.52.0",
]

[[package]]
name = "escape8259"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba4f4911e3666fcd7826997b4745c8224295a6f3072f1418c3067b97a67557ee"
dependencies = [
"rustversion",
]

[[package]]
name = "event-listener"
version = "2.5.3"
Expand Down Expand Up @@ -3900,6 +3910,18 @@ dependencies = [
"vcpkg",
]

[[package]]
name = "libtest-mimic"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fefdf21230d6143476a28adbee3d930e2b68a3d56443c777cae3fe9340eebff9"
dependencies = [
"clap",
"escape8259",
"termcolor",
"threadpool",
]

[[package]]
name = "libz-ng-sys"
version = "1.1.12"
Expand Down Expand Up @@ -7729,9 +7751,9 @@ checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"

[[package]]
name = "walkdir"
version = "2.4.0"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
Expand Down
39 changes: 23 additions & 16 deletions RELEASE_CHECKLIST.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ Start following the steps below to start a release PR. The process is **not ful
8. Now, open a draft PR with a small boilerplate header from the branch which was just pushed:

```
cat <<EOM | gh --repo "${APOLLO_ROUTER_RELEASE_GITHUB_REPO}" pr create --draft -B "main" --title "release: v${APOLLO_ROUTER_RELEASE_VERSION}" --body-file -
cat <<EOM | gh --repo "${APOLLO_ROUTER_RELEASE_GITHUB_REPO}" pr create --draft --label release -B "main" --title "release: v${APOLLO_ROUTER_RELEASE_VERSION}" --body-file -
> **Note**
> **This particular PR must be true-merged to \`main\`.**
Expand Down Expand Up @@ -176,7 +176,7 @@ Start following the steps below to start a release PR. The process is **not ful
- Run our compliance checks and update the `licenses.html` file as appropriate.
- Ensure we're not using any incompatible licenses in the release.
7. Now, review and stage he changes produced by the previous step. This is most safely done using the `--patch` (or `-p`) flag to `git add` (`-u` ignores untracked files).
7. Now, review and stage the changes produced by the previous step. This is most safely done using the `--patch` (or `-p`) flag to `git add` (`-u` ignores untracked files).
```
git add -up .
Expand All @@ -203,11 +203,12 @@ Start following the steps below to start a release PR. The process is **not ful
git push "${APOLLO_ROUTER_RELEASE_GIT_ORIGIN}" "${APOLLO_ROUTER_RELEASE_VERSION}" "v${APOLLO_ROUTER_RELEASE_VERSION}${APOLLO_ROUTER_PRERELEASE_SUFFIX}"
```
11. Finally, publish the Crate from your local computer (this also needs to be moved to CI, but requires changing the release containers to be Rust-enabled and to restore the caches):
11. Finally, publish the Crates from your local computer (this also needs to be moved to CI, but requires changing the release containers to be Rust-enabled and to restore the caches):
> Note: This command may appear unnecessarily specific, but it will help avoid publishing a version to Crates.io that doesn't match what you're currently releasing. (e.g., in the event that you've changed branches in another window)
```
cargo publish -p apollo-federation@"${APOLLO_ROUTER_RELEASE_VERSION}${APOLLO_ROUTER_PRERELEASE_SUFFIX}"
cargo publish -p apollo-router@"${APOLLO_ROUTER_RELEASE_VERSION}${APOLLO_ROUTER_PRERELEASE_SUFFIX}"
```
Expand Down Expand Up @@ -364,15 +365,21 @@ Start following the steps below to start a release PR. The process is **not ful
git pull "${APOLLO_ROUTER_RELEASE_GIT_ORIGIN}" "${APOLLO_ROUTER_RELEASE_VERSION}"
```
6. Use the `gh` CLI to enable **auto-merge** (**_NOT_** auto-**_squash_**):
6. Mark the release PR as **Ready for Review** (it was previously opened as a draft!)
```
gh --repo "${APOLLO_ROUTER_RELEASE_GITHUB_REPO}" pr ready "${APOLLO_ROUTER_RELEASE_VERSION}"
```
7. Use the `gh` CLI to enable **auto-merge** (**_NOT_** auto-**_squash_**):
```
gh --repo "${APOLLO_ROUTER_RELEASE_GITHUB_REPO}" pr merge --merge --body "" -t "release: v${APOLLO_ROUTER_RELEASE_VERSION}" --auto "${APOLLO_ROUTER_RELEASE_VERSION}"
```
7. 🗣️ **Solicit approval from the Router team, wait for the PR to pass CI and auto-merge into `main`**
8. 🗣️ **Solicit approval from the Router team, wait for the PR to pass CI and auto-merge into `main`**
8. After the PR has merged to `main`, pull `main` to your local terminal, and Git tag & push the release:
9. After the PR has merged to `main`, pull `main` to your local terminal, and Git tag & push the release:
This process will kick off the bulk of the release process on CircleCI, including building each architecture on its own infrastructure and notarizing the macOS binary.
Expand All @@ -383,13 +390,13 @@ Start following the steps below to start a release PR. The process is **not ful
git push "${APOLLO_ROUTER_RELEASE_GIT_ORIGIN}" "v${APOLLO_ROUTER_RELEASE_VERSION}"
```
9. Open a PR that reconciles `dev` (Make sure to merge this reconciliation PR back to dev, **do not squash or rebase**):
10. Open a PR that reconciles `dev` (Make sure to merge this reconciliation PR back to dev, **do not squash or rebase**):
```
gh --repo "${APOLLO_ROUTER_RELEASE_GITHUB_REPO}" pr create --title "Reconcile \`dev\` after merge to \`main\` for v${APOLLO_ROUTER_RELEASE_VERSION}" -B dev -H main --body "Follow-up to the v${APOLLO_ROUTER_RELEASE_VERSION} being officially released, bringing version bumps and changelog updates into the \`dev\` branch."
```
10. Mark the PR to **auto-merge NOT auto-squash** using the URL that is output from the previous command
11. Mark the PR to **auto-merge NOT auto-squash** using the URL that is output from the previous command
```
APOLLO_RECONCILE_PR_URL=$(gh --repo "${APOLLO_ROUTER_RELEASE_GITHUB_REPO}" pr list --state open --base dev --head main --json url --jq '.[-1] | .url')
Expand All @@ -398,15 +405,15 @@ Start following the steps below to start a release PR. The process is **not ful
```
11. 🗣️ **Solicit approval from the Router team, wait for the PR to pass CI and auto-merge into `dev`**
12. 🗣️ **Solicit approval from the Router team, wait for the PR to pass CI and auto-merge into `dev`**
12. 👀 Follow along with the process by [going to CircleCI for the repository](https://app.circleci.com/pipelines/github/apollographql/router) and clicking on `release` for the Git tag that appears at the top of the list.
13. 👀 Follow along with the process by [going to CircleCI for the repository](https://app.circleci.com/pipelines/github/apollographql/router) and clicking on `release` for the Git tag that appears at the top of the list.
13. ⚠️ **Wait for `publish_github_release` on CircleCI to finish on this job before continuing.** ⚠️
14. ⚠️ **Wait for `publish_github_release` on CircleCI to finish on this job before continuing.** ⚠️
You should expect this will take at least 30 minutes.
14. Re-create the file you may have previously created called `this_release.md` just to make sure its up to date after final edits from review:
15. Re-create the file you may have previously created called `this_release.md` _just to make sure_ it is up to date after final edits from review:
```
perl -0777 \
Expand All @@ -427,27 +434,27 @@ Start following the steps below to start a release PR. The process is **not ful
CHANGELOG.md > this_release.md
```
15. Change the links in `this_release.md` from `[@username](https://github.com/username)` to `@username` in order to facilitate the correct "Contributorship" attribution on the final GitHub release.
16. Change the links in `this_release.md` from `[@username](https://github.com/username)` to `@username` in order to facilitate the correct "Contributorship" attribution on the final GitHub release.
```
perl -pi -e 's/\[@([^\]]+)\]\([^)]+\)/@\1/g' this_release.md
```
16. Update the release notes on the now-published [GitHub Releases](https://github.com/apollographql/router/releases) (this needs to be moved to CI, but requires `this_release.md` which we just created):
17. Update the release notes on the now-published [GitHub Releases](https://github.com/apollographql/router/releases) (this needs to be moved to CI, but requires `this_release.md` which we just created):
```
gh --repo "${APOLLO_ROUTER_RELEASE_GITHUB_REPO}" release edit v"${APOLLO_ROUTER_RELEASE_VERSION}" -F ./this_release.md
```
17. Finally, publish the Crate from your local computer from the `main` branch (this also needs to be moved to CI, but requires changing the release containers to be Rust-enabled and to restore the caches):
18. Finally, publish the Crate from your local computer from the `main` branch (this also needs to be moved to CI, but requires changing the release containers to be Rust-enabled and to restore the caches):
> Note: This command may appear unnecessarily specific, but it will help avoid publishing a version to Crates.io that doesn't match what you're currently releasing. (e.g., in the event that you've changed branches in another window)
```
cargo publish -p apollo-router@"${APOLLO_ROUTER_RELEASE_VERSION}"
```
18. (Optional) To have a "social banner" for this release, run [this `htmlq` command](https://crates.io/crates/htmlq) (`cargo install htmlq`, or on MacOS `brew install htmlq`; its `jq` for HTML), open the link it produces, copy the image to your clipboard:
19. (Optional) To have a "social banner" for this release, run [this `htmlq` command](https://crates.io/crates/htmlq) (`cargo install htmlq`, or on MacOS `brew install htmlq`; its `jq` for HTML), open the link it produces, copy the image to your clipboard:
```
curl -s "https://github.com/apollographql/router/releases/tag/v${APOLLO_ROUTER_RELEASE_VERSION}" | htmlq 'meta[property="og:image"]' --attribute content
Expand Down
2 changes: 1 addition & 1 deletion apollo-federation/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "apollo-federation"
version = "1.47.0-rc.0"
version = "1.47.0"
authors = ["The Apollo GraphQL Contributors"]
edition = "2021"
description = "Apollo Federation"
Expand Down
17 changes: 12 additions & 5 deletions apollo-federation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[![Join our Discord server](https://img.shields.io/discord/1022972389463687228.svg?color=7389D8&labelColor=6A7EC2&logo=discord&logoColor=ffffff&style=flat-square)](https://discord.gg/graphos)

Apollo Federation
-----------------------------
-----------------
Apollo Federation is an architecture for declaratively composing APIs into a unified graph. Each team can own their slice of the graph independently, empowering them to deliver autonomously and incrementally.

Federation 2 is an evolution of the original Apollo Federation with an improved shared ownership model, enhanced type merging, and cleaner syntax for a smoother developer experience. It’s backwards compatible, requiring no major changes to your subgraphs.
Expand All @@ -15,15 +15,22 @@ Checkout the [Federation 2 docs](https://www.apollographql.com/docs/federation)

## Usage

TODO
This crate is internal to [Apollo Router](https://www.apollographql.com/docs/router/)
and not intended to be used directly.

### CLI tool
## Crate versioning

`cargo fed --help`
The `apollo-federation` crate does **not** adhere to [Semantic Versioning](https://semver.org/).
Any version may have breaking API changes, as this API is expected to only be used by `apollo-router`.
Instead, the version number matches exactly that of the `apollo-router` crate version using it.

This version number is **not** that of the Apollo Federation specification being implemented.
See [Router documentation](https://www.apollographql.com/docs/router/federation-version-support/)
for which Federation versions are supported by which Router versions.

## Contributing

TODO
See [contributing to the `apollo-router` repository](https://github.com/apollographql/router/blob/dev/CONTRIBUTING.md)

## Security

Expand Down
40 changes: 34 additions & 6 deletions apollo-federation/src/error/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::backtrace::Backtrace;
use std::cmp::Ordering;
use std::fmt::Display;
use std::fmt::Formatter;
Expand Down Expand Up @@ -393,8 +394,8 @@ pub struct MultipleFederationErrors {
impl MultipleFederationErrors {
pub fn push(&mut self, error: FederationError) {
match error {
FederationError::SingleFederationError(error) => {
self.errors.push(error);
FederationError::SingleFederationError { inner, .. } => {
self.errors.push(inner);
}
FederationError::MultipleFederationErrors(errors) => {
self.errors.extend(errors.errors);
Expand Down Expand Up @@ -468,20 +469,47 @@ impl Display for AggregateFederationError {
}
}

/// Work around thiserror, which when an error field has a type named `Backtrace`
/// "helpfully" implements `Error::provides` even though that API is not stable yet:
/// <https://github.com/rust-lang/rust/issues/99301>
type ThiserrorTrustMeThisIsTotallyNotABacktrace = Backtrace;

// PORT_NOTE: Often times, JS functions would either throw/return a GraphQLError, return a vector
// of GraphQLErrors, or take a vector of GraphQLErrors and group them together under an
// AggregateGraphQLError which itself would have a specific error message and code, and throw that.
// We represent all these cases with an enum, and delegate to the members.
#[derive(Debug, Clone, thiserror::Error)]
#[derive(thiserror::Error)]
pub enum FederationError {
#[error(transparent)]
SingleFederationError(#[from] SingleFederationError),
#[error("{inner}")]
SingleFederationError {
inner: SingleFederationError,
trace: ThiserrorTrustMeThisIsTotallyNotABacktrace,
},
#[error(transparent)]
MultipleFederationErrors(#[from] MultipleFederationErrors),
#[error(transparent)]
AggregateFederationError(#[from] AggregateFederationError),
}

impl std::fmt::Debug for FederationError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::SingleFederationError { inner, trace } => write!(f, "{inner}\n{trace}"),
Self::MultipleFederationErrors(inner) => std::fmt::Debug::fmt(inner, f),
Self::AggregateFederationError(inner) => std::fmt::Debug::fmt(inner, f),
}
}
}

impl From<SingleFederationError> for FederationError {
fn from(inner: SingleFederationError) -> Self {
Self::SingleFederationError {
inner,
trace: Backtrace::capture(),
}
}
}

impl From<DiagnosticList> for FederationError {
fn from(value: DiagnosticList) -> Self {
let value: MultipleFederationErrors = value.into();
Expand All @@ -496,7 +524,7 @@ impl<T> From<WithErrors<T>> for FederationError {
}

impl FederationError {
pub(crate) fn internal(message: impl Into<String>) -> Self {
pub fn internal(message: impl Into<String>) -> Self {
SingleFederationError::Internal {
message: message.into(),
}
Expand Down
15 changes: 15 additions & 0 deletions apollo-federation/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
//! ## Usage
//!
//! This crate is internal to [Apollo Router](https://www.apollographql.com/docs/router/)
//! and not intended to be used directly.
//!
//! ## Crate versioning
//!
//! The `apollo-federation` crate does **not** adhere to [Semantic Versioning](https://semver.org/).
//! Any version may have breaking API changes, as this API is expected to only be used by `apollo-router`.
//! Instead, the version number matches exactly that of the `apollo-router` crate version using it.
//!
//! This version number is **not** that of the Apollo Federation specification being implemented.
//! See [Router documentation](https://www.apollographql.com/docs/router/federation-version-support/)
//! for which Federation versions are supported by which Router versions.
#![allow(dead_code)] // TODO: This is fine while we're iterating, but should be removed later.

mod api_schema;
Expand Down
8 changes: 4 additions & 4 deletions apollo-federation/src/query_graph/build_query_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1339,10 +1339,10 @@ impl FederatedQueryGraphBuilder {
// like this way in the JS codebase, so we'll mimic the behavior for now.
//
// TODO: This is an optimization to avoid unnecessary inter-conversion between
// the apollo-rs operation representation and the federation-next one. This wasn't a
// the apollo-rs operation representation and the apollo-federation one. This wasn't a
// problem in the JS codebase, as it would use its own operation representation from
// the start. Eventually when operation processing code is ready and we make the switch
// to using the federation-next representation everywhere, we can probably simplify
// to using the apollo-federation representation everywhere, we can probably simplify
// this.
let new_conditions = if all_conditions.len() == 1 {
all_conditions
Expand Down Expand Up @@ -1410,10 +1410,10 @@ impl FederatedQueryGraphBuilder {
// merge the selection sets before into one.
//
// TODO: This is an optimization to avoid unnecessary inter-conversion between
// the apollo-rs operation representation and the federation-next one. This wasn't a
// the apollo-rs operation representation and the apollo-federation one. This wasn't a
// problem in the JS codebase, as it would use its own operation representation from
// the start. Eventually when operation processing code is ready and we make the switch
// to using the federation-next representation everywhere, we can probably simplify
// to using the apollo-federation representation everywhere, we can probably simplify
// this.
let new_conditions = if all_conditions.len() == 1 {
all_conditions
Expand Down
9 changes: 9 additions & 0 deletions apollo-federation/src/query_graph/graph_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,15 @@ impl OpPathElement {
}
}

pub(crate) fn sub_selection_type_position(
&self,
) -> Result<Option<CompositeTypeDefinitionPosition>, FederationError> {
match self {
OpPathElement::Field(field) => Ok(field.data().output_base_type()?.try_into().ok()),
OpPathElement::InlineFragment(inline) => Ok(Some(inline.data().casted_type())),
}
}

pub(crate) fn extract_operation_conditionals(
&self,
) -> Result<Vec<OperationConditional>, FederationError> {
Expand Down
Loading

0 comments on commit f4f0ca7

Please sign in to comment.