Search code examples
azure-devopsazure-pipelinesrepositoryclang-format

Can I set up a single Azure DevOps pipeline to lint/format source files in a PR across multiple repos?


In one sentence, any time a commit is made on a pull request for any of the dozens of repositories, I want this pipeline to run that checks if the source files meet some clang formatting criteria and raise a warning if criteria is not met.

Initially, I just want to format our source files. In the future, we may want to change our formatting schema or add a linter, so this needs to be flexible.

So far, I've set up a pipeline that does this on a single repo. However, this won't work for our project since it's unfeasible to have a separate pipeline for each repo. Any change to the linting/formatting settings on one pipeline would not be applied to the others.

In the case where I set up the pipeline for a single repo, I added a Build Validation policy to the default branch which works as expected.

To expand this solution to the entire project, I added a Build Validation to the default branch (as an optional policy requirement) across all of our repos, then modified the pipeline so that it formats whatever repo triggered it. Within my test PR, I could see the formatting check included by inherited policy, I could see that the build had not yet been run, and I could see a Queue button, but I could not trigger a run by making a commit to the PR OR clicking the Queue button.

Here is what I thought the pipeline COULD look like.

resources:
  repositories:
  - repository: repo_1
    type: git
    name: repo_1
    ref: develop
    trigger:
      branches:
        include:
        - develop
  - repository: repo_2
    type: git
    name: repo_2
    ref: develop
    trigger:
      branches:
        include:
        - develop
  - repository: repo_N
    type: git
    name: repo_N
    ref: develop
    trigger:
      branches:
        include:
        - develop

pool:
  vmImage: 'ubuntu-latest'

steps:
- checkout: self
- checkout: repo_1
- checkout: repo_2
- checkout: repo_N

- task: Bash@3
  displayName: Install Tools
  inputs:
    targetType: 'inline'
    script: |
      sudo apt install clang-format

- task: Bash@3
  displayName: Format Source Files
  inputs:
    targetType: 'inline'
    script: |
      echo "Formatting source files in ... $(Resources.TriggeringAlias)"
      find $(Resources.TriggeringAlias)/src/ -iname *.hpp -o -iname *.cpp | xargs clang-format -style="LLVM" -i

It would setup triggers on develop (default for my org) for all of our repos, format the source files within whatever repo triggered the run, then return the result of that run. Presumably, I would add something to alert whoever submitted the PR that the pipeline made formatting changes, indicating that they should format their source files to match whatever standard we are using, then make another commit.

After digging through the documentation, I'm not confident that DevOps supports what I'm trying to do. The triggers in the .yml above don't activate on a commit to a PR in the way a Build Validation does, only on a PR merge (I presume).

Hopefully I've explained my issue properly. Let me know if I need to provide any more info :)


Solution

  • Based on my understanding, what you expect is that when any repo has a commit, the pipeline can be triggered by the PR. I'm not sure how you configured your build policy, but there is no issue in my test. Below is my YAML and repo information for your reference.

    In my test, there are three repos here, MainRepo, Repo1 and Repo2. The YAML file of the pipeline is stored in MainRepo. The YAML file:

    resources:
     repositories:
       - repository: Repo1
         name: Repo1
         type: git
         trigger:
          branches:
            include:
            - main
       
       - repository: Repo2
         name: Repo2
         type: git
         trigger:
          branches:
            include:
            - main
    
    pool:
      vmImage: ubuntu-latest
    
    steps:
    - checkout: self
    - checkout: Repo1
    - checkout: Repo2
    

    In the YAML, Repo1 and Repo2 are specified as repo resource.

    I configured build policy on all main branches of the repos. enter image description here

    When the PR used to merge from other branches into the main branch has a new commit, the pipeline will be triggered. enter image description here