# Azure Pipelines

Source: https://apigenie.pl/docs/ci/azure-pipelines

An `azure-pipelines.yml` that lints, checks the formatting of and compares an OpenAPI file in every
pull request, as one job with a step per check: each step has its own status in the run, and the
lint report feeds the Tests tab. [Any CI system](/docs/ci) explains the pieces: the commands, the
reports, the installation and the comparison with the target branch.

**Unchecked.** The file follows the Azure Pipelines documentation and has not run on a project on
Azure DevOps. A run on one, passed or failed, reported in an
[issue](https://github.com/mykulyak/api-genie/issues), makes it checked.

## The pipeline

```yaml
# azure-pipelines.yml
trigger: none
pr:
  branches:
    include: ['*']

pool:
  vmImage: ubuntu-latest

steps:
  - script: npm install -g @mykulyak/api-genie
    displayName: Install API Genie

  - script: apigenie lint --formatter junit api/openapi.yaml > $(Build.ArtifactStagingDirectory)/lint.xml
    displayName: Lint

  - task: PublishTestResults@2
    displayName: Publish the lint report
    condition: succeededOrFailed()
    inputs:
      testResultsFormat: JUnit
      testResultsFiles: $(Build.ArtifactStagingDirectory)/lint.xml
      testRunTitle: apigenie lint

  - script: apigenie format --check api/openapi.yaml
    displayName: Check formatting
    condition: succeededOrFailed()

  - script: |
      base="${TARGET#refs/heads/}"
      git fetch --depth=1 origin "$base"
      git show FETCH_HEAD:api/openapi.yaml > base.yaml
      apigenie diff base.yaml api/openapi.yaml
    displayName: Breaking changes
    condition: and(succeededOrFailed(), eq(variables['Build.Reason'], 'PullRequest'))
    env:
      TARGET: $(System.PullRequest.TargetBranch)
```

`pr` triggers the pipeline on the pull requests of a repository on GitHub or Bitbucket; for Azure
Repos, a build validation policy on the target branch, under *Branch policies*, runs it instead.
`succeededOrFailed()` keeps the later steps running after a failed one, so the run shows all three
results. `System.PullRequest.TargetBranch` is `refs/heads/main` for Azure Repos and `main` for
GitHub; the step strips the prefix.

## What the pull request shows

- The status of the pipeline, as a check on GitHub or as the policy's status on Azure Repos. A
  failed step fails the run.
- The Tests tab of the run, from the JUnit report: a failed test per lint issue, named
  `apigenie.<rule>`, with the message. The task does not fail on failed tests, so the step's exit
  status alone decides, and warnings do not fail it.
- The logs of the steps: the files that would change, and the changes with their severity.

The *SARIF SAST Scans Tab* extension from the marketplace adds a Scans tab to the run that reads
SARIF files from a published artifact named `CodeAnalysisLogs`; `apigenie lint --formatter sarif`
writes one.
