• Azure DevOps PowerShell Scripts - List all Azure Pipelines

    Azure Pipelines logo If you want to list all the Azure Pipelines for all projects in an Azure DevOps organisation, this script will return a list of their names.

    See Personal access tokens for instructions on how to create the personal access token.

    param (
        [string] $organisation,
        [string] $personalAccessToken
    )
    
    $base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalAccessToken)"))
    $headers = @{Authorization=("Basic {0}" -f $base64AuthInfo)}
    
    $result = Invoke-RestMethod -Uri "https://dev.azure.com/$organisation/_apis/projects?api-version=6.0" -Method Get -Headers $headers
    
    $projectNames = $result.value.name
    
    $projectNames | ForEach-Object {
        $project = $_
    
        $result = Invoke-RestMethod -Uri "https://dev.azure.com/$organisation/$project/_apis/pipelines?api-version=6.0-preview.1" -Method Get -Headers $headers
    
        $result.value.name
    } | Sort-Object
    

    It makes use of the Pipelines - List REST API, so you could ask for any of the other properties instead of or in addition to name as well.

  • Azure DevOps PowerShell Scripts - List all Git repositories

    Azure Repos logo If you want to list all the Git repositories for all projects in an Azure DevOps organisation, this script will return all the remote URLs.

    See Personal access tokens for instructions on how to create the personal access token.

    param (
        [string] $organisation,
        [string] $personalAccessToken
    )
    
    $base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalAccessToken)"))
    $headers = @{Authorization=("Basic {0}" -f $base64AuthInfo)}
    
    $result = Invoke-RestMethod -Uri "https://dev.azure.com/$organisation/_apis/projects?api-version=6.0" -Method Get -Headers $headers
    
    $projectNames = $result.value.name
    
    $projectNames | ForEach-Object {
        $project = $_
    
        $result = Invoke-RestMethod -Uri "https://dev.azure.com/$organisation/$project/_apis/git/repositories?api-version=6.0" -Method Get -Headers $headers
    
        $result.value.remoteUrl
    } | Sort-Object
    

    It makes use of the Repositories - List REST API, so you could ask for any of the other properties instead of or in addition to remoteUrl as well.

  • Using GitHub Actions to update packages.lock.json for Dependabot PRs

    I like using Dependabot to keep my package dependencies up to date. But it does have one problem if you’re using packages.lock.json files with NuGet packages - it doesn’t update them. So your csproj will be modified but the packages.lock.json file won’t, which can lead to broken failing.

    Build failure

    Here’s one approach to working around this. Hopefully GitHub will fix this properly in the future.

    ChatOps

    I’m going to make use of Peter Evans’ Slash Command Dispatch GitHub Action to enable triggering by entering /lockfiles as a comment on the pull request. This action is extensible and can be used to create all kinds of ‘slash’ commands.

    First up, I created a new workflow that uses this action:

    name: Slash Command Dispatch
    on:
      issue_comment:
        types: [created]
    jobs:
      slashCommandDispatch:
        runs-on: ubuntu-latest
        steps:
    
          - uses: xt0rted/pull-request-comment-branch@v1
            id: comment-branch
    
          - name: Slash Command Dispatch
            uses: peter-evans/slash-command-dispatch@v2
            id: slash-command
            with:
              token: ${{ secrets.PAT_REPO_FULL }}
              commands: |
                lockfiles
              permission: write
              issue-type: pull-request
              dispatch-type: workflow
              static-args: ref=${{ steps.comment-branch.outputs.head_ref }}
    
    

    Things to note:

    • We’re triggering on a new comment being added to a pull request
    • We use Pull Request Comment Branch Action to obtain the name of the branch that is linked to the pull request for the triggering comment.
    • The dispatch-type is set to workflow as we want the secondary workflow to run against the pull request branch (not the default branch)
    • We set the ref argument to the branch name. This will be picked up by the second workflow.

    The second workflow is named lockfiles-command.yml. It needs to follow the convention of commandname-command.yml.

    name: Update lockfiles
    on:
      workflow_dispatch:
    
    jobs:
      lockfiles:
        runs-on: ubuntu-latest
        steps:
    
          - uses: actions/checkout@v2
            with:
              fetch-depth: 0
              token: ${{ secrets.PAT_REPO_FULL }}
    
          - name: Setup .NET 5
            uses: actions/setup-dotnet@v1
            with:
              dotnet-version: 5.0.x
    
          - name: Restore dependencies
            run: dotnet restore --force-evaluate
    
          - uses: stefanzweifel/git-auto-commit-action@v4
            with:
              commit_message: Update lockfiles
    
    

    Things to note:

    • This workflow uses the workflow_dispatch trigger.
    • The checkout action notices that the ref value was set in the first workflow and so will checkout the pull request branch.
    • We use the git-auto-commit Action to commit and push any changes made by the earlier dotnet restore command.

    To trigger the workflow, add a new comment to a pull request with /lockfiles. eg.

    GitHub pull request comment

    You can see a complete repo with example pull request over at https://github.com/flcdrg/dependabot-lockfiles/pull/1

    Future ideas

    It could be possible to have this workflow trigger automatically after Dependabot creates the pull request if you wanted to completely automate this approach, rather than needing to add the comment manually.