diff --git a/.gitbook/assets/Screenshot 2022-12-01 at 2.05.00 PM.png b/.gitbook/assets/Screenshot 2022-12-01 at 2.05.00 PM.png
new file mode 100644
index 00000000..fd93a201
Binary files /dev/null and b/.gitbook/assets/Screenshot 2022-12-01 at 2.05.00 PM.png differ
diff --git a/.gitbook/assets/Screenshot 2022-12-01 at 2.05.59 PM.png b/.gitbook/assets/Screenshot 2022-12-01 at 2.05.59 PM.png
new file mode 100644
index 00000000..431d5463
Binary files /dev/null and b/.gitbook/assets/Screenshot 2022-12-01 at 2.05.59 PM.png differ
diff --git a/.gitbook/assets/Screenshot 2022-12-02 at 9.28.28 AM (1).png b/.gitbook/assets/Screenshot 2022-12-02 at 9.28.28 AM (1).png
new file mode 100644
index 00000000..4296c19c
Binary files /dev/null and b/.gitbook/assets/Screenshot 2022-12-02 at 9.28.28 AM (1).png differ
diff --git a/.gitbook/assets/Screenshot 2022-12-02 at 9.28.28 AM.png b/.gitbook/assets/Screenshot 2022-12-02 at 9.28.28 AM.png
new file mode 100644
index 00000000..4296c19c
Binary files /dev/null and b/.gitbook/assets/Screenshot 2022-12-02 at 9.28.28 AM.png differ
diff --git a/.gitbook/assets/Screenshot 2022-12-02 at 9.43.37 AM.png b/.gitbook/assets/Screenshot 2022-12-02 at 9.43.37 AM.png
new file mode 100644
index 00000000..176d97d8
Binary files /dev/null and b/.gitbook/assets/Screenshot 2022-12-02 at 9.43.37 AM.png differ
diff --git a/SUMMARY.md b/SUMMARY.md
index 1f1f3109..58bcad6b 100644
--- a/SUMMARY.md
+++ b/SUMMARY.md
@@ -23,6 +23,7 @@
* [Configure an agent with Maven repository access](how-to/on-premise-agent/maven-repository-integration/configure-an-agent-with-maven-repository-access.md)
* [Configure an agent with Artifactory access](how-to/on-premise-agent/maven-repository-integration/configure-an-agent-with-artifactory-access.md)
* [🚀 Accessing the Moderne API](how-to/accessing-the-moderne-api.md)
+* [Recipe Execution and Commits with GraphQL](how-to/recipe-execution-and-commits-with-graphql.md)
## Releases
diff --git a/how-to/recipe-execution-and-commits-with-graphql.md b/how-to/recipe-execution-and-commits-with-graphql.md
new file mode 100644
index 00000000..8e82a778
--- /dev/null
+++ b/how-to/recipe-execution-and-commits-with-graphql.md
@@ -0,0 +1,483 @@
+# Recipe Execution and Commits with GraphQL
+
+Imagine you found a recipe you would like to run as part of your organization's automation process (such as updating the Gradle plugin version when a new release is published). Rather than manually running this recipe each time, you can use Moderne's GraphQL API to speed this process up with automation.
+
+To help you understand how to automate recipe execution and commits, we'll walk through all the steps necessary to use Moderne's GraphQL API. By the end, you should know how to:
+
+* [Execute recipes](recipe-execution-and-commits-with-graphql.md#recipe-execution)
+* [Verify that recipes have been completed](recipe-execution-and-commits-with-graphql.md#verify-recipe-completion)
+* [Retrieve repository results](recipe-execution-and-commits-with-graphql.md#retrieve-repositories-with-results)
+* [Commit changes](recipe-execution-and-commits-with-graphql.md#creating-a-pull-request)
+* [Ensure that committed changes are correct](recipe-execution-and-commits-with-graphql.md#verify-commit-job)
+
+### Prerequisites:
+
+This guide assumes that you:
+
+1. Know how to use and interact with GraphQL APIs.
+2. Have already [created a Moderne personal access token](../references/create-api-access-tokens.md).
+3. Have authorized your SCM provider in the Moderne UI to be able to retrieve diffs and perform commits. **Note:** SCM authentication tokens expire every 8 hours and can only be renewed via the Moderne UI at this time. \
+ To authorize click the SCM icon of your choice in the header:
+
+
+
+### Recipe Execution
+
+1. Click the [Repository Group](../references/managing-repository-groups.md) selector on the right-hand side of the header and create a new group of your selected repositories.\
+
+
+
+2. Navigate to the recipe you wish to run and fill out the recipe options.\
+
+
+
+3. Click the `See how to run against the API` link. This will provide you with the query that will be run when executing a recipe run and additionally the variables provided from your repository group in the query variables pane.
+4. You can then execute a recipe with the following mutation:
+
+{% tabs %}
+{% tab title="Execute Recipe Mutation" %}
+```graphql
+mutation executeRecipe($input: RecipeRunInput!) {
+ runRecipe(run: $input) {
+ id
+ }
+}
+```
+{% endtab %}
+
+{% tab title="Mutation Variables" %}
+```json
+{
+ "input": {
+ "recipe": {
+ "id": "org.openrewrite.gradle.plugins.UpgradePluginVersion",
+ "options": [
+ { "name": "pluginIdPattern", "value": "com.gradle.plugin-publish" },
+ { "name": "newVersion", "value": "1.1.0" }
+ ]
+ },
+ "repositoryFilter": [
+ {
+ "branch": "master",
+ "origin": "github.com",
+ "path": "gradle-dependency-analyze/gradle-dependency-analyze"
+ },
+ {
+ "branch": "master",
+ "origin": "github.com",
+ "path": "gradle/gradle-checksum"
+ }
+ ]
+ }
+}
+```
+{% endtab %}
+
+{% tab title="cURL" %}
+{% code overflow="wrap" %}
+```shell
+curl --request POST
+--url https://api.public.moderne.io/graphql
+--header 'Authorization: Bearer '
+--header 'Content-Type: application/json'
+--data '{"query":"# Moderne API: https://api.public.moderne.io/graphql\nmutation executeRecipe($input: RecipeRunInput!) {\nrunRecipe(run: $input) {\n id\n}\n}","variables":{"input":{"recipe":{"id":"org.openrewrite.gradle.plugins.UpgradePluginVersion","options":[{"name":"pluginIdPattern","value":"nebula.maven-nebula-publish"},{"name":"newVersion","value":"19"}]},"repositoryFilter":[{"branch":"main","origin":"github.com","path":"moderneinc/eureka-server"},{"branch":"main","origin":"github.com","path":"moderneinc/moderne-agent-model"},{"branch":"main","origin":"github.com","path":"moderneinc/moderne-agent"}]}},"operationName":"executeRecipe"}'
+```
+{% endcode %}
+{% endtab %}
+{% endtabs %}
+
+5\. The mutation will return a response that contains the `id` of the recipe run which will be used in the next step to poll for the completion of the recipe. Example response:
+
+```graphql
+{
+ "data": {
+ "runRecipe": {
+ "id": "5LPSt"
+ }
+ }
+}
+```
+
+### Verify recipe completion
+
+1. You will now need to poll (Moderne's web interface uses a 3-second interval) with the query shown below using the `id` from the [recipe execution mutation](recipe-execution-and-commits-with-graphql.md#recipe-execution).
+
+{% tabs %}
+{% tab title="Query Recipe Run" %}
+```graphql
+query runRecipeName($id: ID!) {
+ recipeRun(id: $id) {
+ recipe {
+ id
+ name
+ }
+ state
+ }
+}
+```
+{% endtab %}
+
+{% tab title="Query Variables" %}
+```json
+{ "id": "sI1M0" }
+```
+{% endtab %}
+
+{% tab title="cURL" %}
+{% code overflow="wrap" %}
+```shell
+curl --request POST
+--url https://api.public.moderne.io/graphql
+--header 'Authorization: Bearer '
+--header 'Content-Type: application/json'
+--data '{"query":"# Moderne API: https://api.public.moderne.io/graphql\nquery runRecipeName($id: ID!) {\n recipeRun(id: $id) {\n recipe {\n id\n name\n **typename\n }\n state\n **typename\n }\n}","variables":{"id":"sI1M0"},"operationName":"runRecipeName"}'
+```
+{% endcode %}
+{% endtab %}
+{% endtabs %}
+
+2\. Once you receive a response with a `FINISHED` or `ERROR` state, you can then retrieve the repositories where changes were made. Example response:
+
+```json
+{
+ "data": {
+ "recipeRun": {
+ "recipe": {
+ "id": "org.openrewrite.gradle.plugins.UpgradePluginVersion",
+ "name": "Update a Gradle plugin by id"
+ },
+ "state": "FINISHED"
+ }
+ }
+}
+```
+
+### Retrieve repositories with results
+
+1. Using the `id` from the [recipe execution](recipe-execution-and-commits-with-graphql.md#recipe-execution) response, you can now retrieve the repositories where changes were made using the query below.
+
+{% tabs %}
+{% tab title="Retrieve Repositories Query" %}
+```graphql
+query selectAllRepositoriesWithResults($id: ID!, $first: Int, $after: String) {
+ recipeRun(id: $id) {
+ summaryResultsPages(
+ first: $first
+ after: $after
+ filterBy: { onlyWithResults: true }
+ ) {
+ count
+ pageInfo {
+ hasNextPage
+ endCursor
+ }
+ edges {
+ node {
+ repository {
+ __typename
+ origin
+ path
+ branch
+ }
+ state
+ }
+ }
+ }
+ }
+}
+```
+{% endtab %}
+
+{% tab title="Query Variables" %}
+```json
+{
+ "id": "XHxCx",
+ "first": 100 // This is page size. Should your result set exceed this you will need to loop and re-query for the next page(s) until hasNextPage is false in the result.
+}
+```
+{% endtab %}
+
+{% tab title="cURL" %}
+{% code overflow="wrap" %}
+```shell
+curl --request POST
+--url https://api.public.moderne.io/graphql
+--header 'Authorization: Bearer YOUR MODERNE TOKEN HERE'
+--header 'Content-Type: application/json'
+--data '{"query":"query selectAllRepositoriesWithResults($id: ID!, $first: Int, $after: String) {\n recipeRun(id: $id) {\n summaryResultsPages(\n first: $first\n after: $after\n filterBy: { onlyWithResults: true }\n ) {\n count\n pageInfo {\n hasNextPage\n endCursor\n }\n edges {\n node {\n repository {\n __typename\n origin\n path\n branch\n }\n state\n }\n }\n }\n\t}\n}","variables":{"id":"XHxCx"},"operationName":"selectAllRepositoriesWithResults"}'
+```
+{% endcode %}
+{% endtab %}
+{% endtabs %}
+
+2\. You can then use the `edges` array in the response, to build up the repository list that will be used in the next step of creating a pull request. Example response:
+
+```json
+{
+ "data": {
+ "recipeRun": {
+ "summaryResultsPages": {
+ "count": 1,
+ "pageInfo": {
+ "hasNextPage": false,
+ "endCursor": "0"
+ },
+ "edges": [
+ {
+ "node": {
+ "repository": {
+ "__typename": "GitHubRepository",
+ "origin": "github.com",
+ "path": "gradle/gradle-checksum",
+ "branch": "master"
+ },
+ "state": "FINISHED"
+ }
+ }
+ ]
+ }
+ }
+ }
+}
+```
+
+### Creating a pull request
+
+1. Next, we will perform the `pullRequest` mutation to create a pull request with our changes. We will be using the`id` from [recipe execution ](recipe-execution-and-commits-with-graphql.md#recipe-execution)and the response from the previous step to construct the mutation variables for committing a pull request. See the mutation variables tab below.
+
+{% tabs %}
+{% tab title="Pull Request Mutation" %}
+```graphql
+mutation pullRequest(
+ $commitInput: CommitInput!
+ $pullRequestTitle: String
+ $pullRequestBody: Base64
+ $isDraft: Boolean! = false
+) {
+ pullRequest(
+ commit: $commitInput
+ pullRequestTitle: $pullRequestTitle
+ pullRequestBody: $pullRequestBody
+ draft: $isDraft
+ ) {
+ id
+ started
+ email
+ completed
+ summaryResults {
+ count
+ successfulCount
+ failedCount
+ noChangeCount
+ }
+ }
+}
+```
+{% endtab %}
+
+{% tab title="Mutation Variables" %}
+```graphql
+{
+ "isDraft": false,
+ "commitInput": {
+ "recipeRunId": "Dxvsv",
+ "branchName": "refactor/update-a-gradle-plugin-by-id",
+ "message": "refactor: Update a Gradle plugin by id",
+ "repositories": [
+ {
+ "branch": "master",
+ "origin": "github.com",
+ "path": "gradle/gradle-checksum"
+ },
+ {
+ "branch": "master",
+ "origin": "github.com",
+ "path": "gradle-nexus/publish-plugin"
+ }
+ ]
+ },
+ "pullRequestTitle": "refactor: Update a Gradle plugin by id", // Optional
+ "pullRequestBody": "refactor: Update a Gradle plugin by id" // Optional
+}
+```
+{% endtab %}
+
+{% tab title="cURL" %}
+{% code overflow="wrap" %}
+```shell
+curl --request POST
+--url https://api.public.moderne.io/graphql
+--header 'Authorization: Bearer '
+--header 'Content-Type: application/json'
+--data '{"query":"mutation pullRequest(\n $commitInput: CommitInput!\n $pullRequestTitle: String\n $pullRequestBody: Base64\n $isDraft: Boolean! = false\n) {\n commit: pullRequest(\n commit: $commitInput\n pullRequestTitle: $pullRequestTitle\n pullRequestBody: $pullRequestBody\n draft: $isDraft\n ) {\n id\n started\n email\n completed\n summaryResults {\n count\n successfulCount\n failedCount\n noChangeCount\n **typename\n }\n **typename\n }\n}","variables":{"isDraft":false,"commitInput":{"recipeRunId":"Dxvsv","branchName":"refactor/update-a-gradle-plugin-by-id","message":"refactor: Update a Gradle plugin by id","repositories":[{"branch":"master","origin":"github.com","path":"gradle/gradle-checksum"},{"branch":"master","origin":"github.com","path":"gradle-nexus/publish-plugin"}]},"pullRequestTitle":"refactor: Update a Gradle plugin by id","pullRequestBody":"refactor: Update a Gradle plugin by id"},"operationName":"pullRequest"}'
+```
+{% endcode %}
+{% endtab %}
+{% endtabs %}
+
+2\. Once the mutation is executed we will receive a response with the commit `id` that we can then use to poll for the completion of the commit. Example response:
+
+```json
+{
+ "data": {
+ "pullRequest": {
+ "id": "c83315a1-397f-44cb-9ef2-9a2ca195dda6",
+ "started": "2022-12-01T22:46:01.818313Z",
+ "email": "dev@null",
+ "completed": 0,
+ "summaryResults": {
+ "count": 1,
+ "successfulCount": 0,
+ "failedCount": 0,
+ "noChangeCount": 0
+ }
+ }
+ }
+}
+```
+
+### Verify commit job
+
+1. Using the `id` returned from the [pull request mutation](recipe-execution-and-commits-with-graphql.md#creating-a-pull-request) we can then poll for the completion of the commit job. When the response is returned with the `completed` property set to `1` the job has been completed. The `summaryResults` property will contain the count of success, failure, no changes commit jobs. Detailed statuses are found on the `commits` property. This is a paginated query so you may need to loop through multiple pages if you wish to see detailed results for each commit.
+
+{% tabs %}
+{% tab title="Commit Job Query" %}
+```graphql
+query commitJob(
+ $id: ID!
+ $first: Int = 50
+ $after: String
+ $filterBy: CommitJobFilterInput
+ $orderBy: CommitJobOrderInput
+) {
+ commitJob(id: $id) {
+ id
+ started
+ email
+ completed
+ summaryResults {
+ count
+ successfulCount
+ failedCount
+ noChangeCount
+ }
+ recipeRunId
+ message
+ extendedMessage
+ options {
+ ... on PullRequestOptions {
+ branchName
+ draft
+ pullRequestBody
+ pullRequestTitle
+ }
+ }
+ started
+ commits(
+ first: $first
+ after: $after
+ filterBy: $filterBy
+ orderBy: $orderBy
+ ) {
+ pageInfo {
+ hasNextPage
+ endCursor
+ }
+ count
+ edges {
+ node {
+ state
+ stateMessage
+ modified
+ repository {
+ origin
+ path
+ branch
+ ... on GitHubRepository {
+ organization
+ name
+ ingested
+ }
+ }
+ resultLink
+ }
+ }
+ }
+ }
+}
+```
+{% endtab %}
+
+{% tab title="Query Variables" %}
+```json
+{
+ "first": 50, // Page size
+ "id": "c83315a1-397f-44cb-9ef2-9a2ca195dda6"
+}{
+```
+{% endtab %}
+
+{% tab title="cURL" %}
+{% code overflow="wrap" %}
+```shell
+curl --request POST \
+ --url https://api.public.moderne.io/graphql \
+ --header 'Authorization: Bearer ' \
+ --header 'Content-Type: application/json' \
+ --data '{"query":"query commitJob(\n $id: ID!\n $first: Int = 50\n $after: String\n $filterBy: CommitJobFilterInput\n $orderBy: CommitJobOrderInput\n) {\n commitJob(id: $id) {\n id\n started\n email\n completed\n summaryResults {\n count\n successfulCount\n failedCount\n noChangeCount\n __typename\n }\n __typename\n recipeRunId\n message\n extendedMessage\n options {\n ... on PullRequestOptions {\n branchName\n draft\n pullRequestBody\n pullRequestTitle\n __typename\n }\n __typename\n }\n started\n commits(\n first: $first\n after: $after\n filterBy: $filterBy\n orderBy: $orderBy\n ) {\n pageInfo {\n hasNextPage\n endCursor\n __typename\n }\n count\n edges {\n node {\n state\n stateMessage\n modified\n repository {\n origin\n path\n branch\n ... on GitHubRepository {\n organization\n name\n ingested\n __typename\n }\n __typename\n }\n resultLink\n __typename\n }\n __typename\n }\n __typename\n }\n __typename\n }\n}\n","variables":{"first":50,"id":"c83315a1-397f-44cb-9ef2-9a2ca195dda6"},"operationName":"commitJob"}'
+```
+{% endcode %}
+{% endtab %}
+{% endtabs %}
+
+2\. Example response:
+
+```json
+{
+ "data": {
+ "commitJob": {
+ "id": "c83315a1-397f-44cb-9ef2-9a2ca195dda6",
+ "started": "2022-12-01T22:46:01.818313Z",
+ "email": "dev@null.com",
+ "completed": 1,
+ "summaryResults": {
+ "count": 1,
+ "successfulCount": 1,
+ "failedCount": 0,
+ "noChangeCount": 0
+ },
+ "recipeRunId": "NazKj",
+ "message": "refactor: Update a Gradle plugin by id",
+ "extendedMessage": null,
+ "options": {
+ "branchName": "refactor/update-a-gradle-plugin-by-id",
+ "draft": false,
+ "pullRequestBody": null,
+ "pullRequestTitle": null
+ },
+ "commits": {
+ "pageInfo": {
+ "hasNextPage": false,
+ "endCursor": "c2ltcGxlLWN1cnNvcjA="
+ },
+ "count": 1,
+ "edges": [
+ {
+ "node": {
+ "state": "COMPLETED",
+ "stateMessage": null,
+ "modified": "2022-12-01T22:46:01.818313Z",
+ "repository": {
+ "branch": "master",
+ "origin": "github.com",
+ "path": "gradle/gradle-checksum"
+ },
+ "resultLink": "https://github.com/gradle/gradle-checksum/pull/14"
+ }
+ }
+ ]
+ }
+ }
+ }
+}
+```