From 43f7a39fe4db441d1d79a8b11d9454d8bd41f61b Mon Sep 17 00:00:00 2001 From: Isaac Mann Date: Thu, 2 Mar 2023 13:07:40 -0500 Subject: [PATCH] docs(core): last successful commit in Azure (#15321) Co-authored-by: Benjamin Cabanes <3447705+bcabanes@users.noreply.github.com> --- docs/generated/manifests/menus.json | 16 ++++ docs/generated/manifests/recipes.json | 20 +++++ docs/map.json | 6 +- docs/shared/monorepo-ci-azure.md | 2 +- .../recipes/azure-last-successful-commit.md | 82 +++++++++++++++++++ 5 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 docs/shared/recipes/azure-last-successful-commit.md diff --git a/docs/generated/manifests/menus.json b/docs/generated/manifests/menus.json index 4f4f1930be..00745b34ae 100644 --- a/docs/generated/manifests/menus.json +++ b/docs/generated/manifests/menus.json @@ -2717,6 +2717,14 @@ "children": [], "disableCollapsible": false }, + { + "name": "Find the Last Successful Commit in Azure Pipelines", + "path": "/recipes/other/azure-last-successful-commit", + "id": "azure-last-successful-commit", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Troubleshoot Cache Misses", "path": "/recipes/other/troubleshoot-cache-misses", @@ -2968,6 +2976,14 @@ "children": [], "disableCollapsible": false }, + { + "name": "Find the Last Successful Commit in Azure Pipelines", + "path": "/recipes/other/azure-last-successful-commit", + "id": "azure-last-successful-commit", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Troubleshoot Cache Misses", "path": "/recipes/other/troubleshoot-cache-misses", diff --git a/docs/generated/manifests/recipes.json b/docs/generated/manifests/recipes.json index ee1e886efe..097a186a39 100644 --- a/docs/generated/manifests/recipes.json +++ b/docs/generated/manifests/recipes.json @@ -1245,6 +1245,16 @@ "path": "/recipes/other/dte", "tags": [] }, + { + "id": "azure-last-successful-commit", + "name": "Find the Last Successful Commit in Azure Pipelines", + "description": "", + "file": "shared/recipes/azure-last-successful-commit", + "itemList": [], + "isExternal": false, + "path": "/recipes/other/azure-last-successful-commit", + "tags": [] + }, { "id": "troubleshoot-cache-misses", "name": "Troubleshoot Cache Misses", @@ -1560,6 +1570,16 @@ "path": "/recipes/other/dte", "tags": [] }, + "/recipes/other/azure-last-successful-commit": { + "id": "azure-last-successful-commit", + "name": "Find the Last Successful Commit in Azure Pipelines", + "description": "", + "file": "shared/recipes/azure-last-successful-commit", + "itemList": [], + "isExternal": false, + "path": "/recipes/other/azure-last-successful-commit", + "tags": [] + }, "/recipes/other/troubleshoot-cache-misses": { "id": "troubleshoot-cache-misses", "name": "Troubleshoot Cache Misses", diff --git a/docs/map.json b/docs/map.json index 7b11caf9d6..e1cee6ad28 100644 --- a/docs/map.json +++ b/docs/map.json @@ -1143,7 +1143,11 @@ "id": "dte", "file": "shared/examples/dte" }, - + { + "name": "Find the Last Successful Commit in Azure Pipelines", + "id": "azure-last-successful-commit", + "file": "shared/recipes/azure-last-successful-commit" + }, { "name": "Troubleshoot Cache Misses", "id": "troubleshoot-cache-misses", diff --git a/docs/shared/monorepo-ci-azure.md b/docs/shared/monorepo-ci-azure.md index 7bfb9e2ef9..db055c34ef 100644 --- a/docs/shared/monorepo-ci-azure.md +++ b/docs/shared/monorepo-ci-azure.md @@ -2,7 +2,7 @@ Below is an example of an Azure Pipelines setup for an Nx workspace - building and testing only what is affected. -Unlike `GitHub Actions` and `CircleCI`, you don't have the metadata to help you track the last successful run on `main`. In the example below, the base is set to `HEAD~1` (for push) or branching point (for pull requests), but a more robust solution would be to tag an SHA in the main job once it succeeds and then use this tag as a base. See the [nx-tag-successful-ci-run](https://github.com/nrwl/nx-tag-successful-ci-run) and [nx-set-shas](https://github.com/nrwl/nx-set-shas) (version 1 implements tagging mechanism) repositories for more information. +Unlike `GitHub Actions` and `CircleCI`, you don't have the metadata to help you track the last successful run on `main`. In the example below, the base is set to `HEAD~1` (for push) or branching point (for pull requests), but a more robust solution would be to tag an SHA in the main job once it succeeds and then use this tag as a base. You can also try [using the devops CLI within the pipeline yaml](/recipes/other/azure-last-successful-commit). See the [nx-tag-successful-ci-run](https://github.com/nrwl/nx-tag-successful-ci-run) and [nx-set-shas](https://github.com/nrwl/nx-set-shas) (version 1 implements tagging mechanism) repositories for more information. We also have to set `NX_BRANCH` explicitly. diff --git a/docs/shared/recipes/azure-last-successful-commit.md b/docs/shared/recipes/azure-last-successful-commit.md new file mode 100644 index 0000000000..41e7252b62 --- /dev/null +++ b/docs/shared/recipes/azure-last-successful-commit.md @@ -0,0 +1,82 @@ +# Get the Commit of the Last Successful Build in Azure Pipelines + +The idea is to use [Azure Devops CLI](https://learn.microsoft.com/en-us/cli/azure/pipelines?view=azure-cli-latest) +directly in the [Pipeline Yaml](https://learn.microsoft.com/en-us/azure/devops/cli/azure-devops-cli-in-yaml?view=azure-devops) + +First, we configure Devops CLI + +```yaml +# Set Azure Devops default settings +- bash: az devops configure --defaults organization=$(System.TeamFoundationCollectionUri) project=$(System.TeamProject) + displayName: 'Configure Azure DevOps organization and project' +``` + +Then we can query the pipelines API (providing the auth token) + +```yaml +# Get last successfully commit infos from Azure Devops +- bash: | + LAST_SHA=$(az pipelines build list --branch $(Build.SourceBranchName) --definition-ids $(System.DefinitionId) --result succeeded --top 1 --query "[0].triggerInfo.\"ci.sourceSha\"") + echo "Last successful commit SHA: $LAST_SHA" + echo "##vso[task.setvariable variable=BASE_SHA]$LAST_SHA" + displayName: 'Get last successful commit SHA' + env: + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) +``` + +We can target a specific build, in this example we specified: + +- The branch (--branch) +- The pipeline Id (--definition-ids) +- The result type (--result) +- The number of result (-top) + +By default the command returns an entire JSON object with all the information. But we can narrow it down to the desired result with the `--query` param that uses [JMESPath](https://jmespath.org/) format ([more details](https://learn.microsoft.com/en-us/cli/azure/query-azure-cli?tabs=concepts%2Cbash)) + +Finally we extract the result in a common [custom variable](https://learn.microsoft.com/en-us/azure/devops/pipelines/process/set-variables-scripts?view=azure-devops&tabs=bash) named `BASE_SHA` used later by `nx affected` commands + +An example with a default SHA in case no commit is found: + +```yaml {% fileName="azure-pipelines.yml" %} +trigger: + - main +pr: + - main + +variables: + CI: 'true' + NX_BRANCH: $(Build.SourceBranchName) + DEFAULT_BASE_SHA: $(git rev-parse HEAD~1) + HEAD_SHA: $(git rev-parse HEAD) + +jobs: + - job: main + pool: + vmImage: 'ubuntu-latest' + steps: + # Set Azure Devops CLI default settings + - bash: az devops configure --defaults organization=$(System.TeamFoundationCollectionUri) project=$(System.TeamProject) + displayName: 'Set default Azure DevOps organization and project' + + # Get last successfull commit from Azure Devops CLI + - bash: | + LAST_SHA=$(az pipelines build list --branch $(Build.SourceBranchName) --definition-ids $(System.DefinitionId) --result succeeded --top 1 --query "[0].triggerInfo.\"ci.sourceSha\"") + if [ -z "$LAST_SHA" ] + then + LAST_SHA=$DEFAULT_BASE_SHA + fi + echo "Last successful commit SHA: $LAST_SHA" + echo "##vso[task.setvariable variable=BASE_SHA]$LAST_SHA" + displayName: 'Get last successful commit SHA' + env: + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + + - script: npm ci + + - script: npx nx workspace-lint + - script: npx nx format:check + + - script: npx nx affected --base=$(BASE_SHA) --target=lint --parallel=3 + - script: npx nx affected --base=$(BASE_SHA) --target=test --parallel=3 --ci --code-coverage + - script: npx nx affected --base=$(BASE_SHA) --target=build --parallel=3 +```