Azure / azure-devops-cli-extension

Azure DevOps Extension for Azure CLI
https://docs.microsoft.com/en-us/cli/azure/ext/azure-devops/?view=azure-cli-latest
MIT License
632 stars 241 forks source link

[Bug] Inability to set BuildOption during pipelines create/update causes pipeline triggers to not fire #953

Open aglorei opened 4 years ago

aglorei commented 4 years ago

Describe the bug A clear and concise description of what the bug is.

To Reproduce Azure Cli Version: Azure-Devops extension version:

{
  "azure-cli": "2.0.80",
  "azure-cli-command-modules-nspkg": "2.0.3",
  "azure-cli-core": "2.0.80",
  "azure-cli-nspkg": "3.0.4",
  "azure-cli-telemetry": "1.0.4",
  "extensions": {
    "azure-devops": "0.17.0"
  }
}

Steps to reproduce the behavior:

  1. Use PAT to authenticate (I set it as an environment variable AZURE_DEVOPS_EXT_PAT per documentation.
  2. Ensure a scenario where an upstream pipeline "a" triggers pipeline "b" by utilizing a pipeline resource with trigger and branch filter in the downstream pipeline. Example:
    #azure-pipelines-a.yml
    jobs:
    - job: A
    pool:
      vmImage: ubuntu-18.04
    steps:
      - task: Bash@3
        displayName: Test
        inputs:
          targetType: inline
          script: |
            echo "Running testa"
            sleep 10

    and

    
    #azure-pipelines-b.yml
    resources:
    pipelines:
    - pipeline: ci
      source: testa
      trigger:
        branches:
          - develop

jobs:

Expected behavior Allow setting of BuildOptions, which is what I believe shows up from this manual interation, in order to set definition id 5d58cc01-7c75-450c-be18-a388ddb129ec and allow for triggers from upstream.

Additional context The changes to the build object are recorded and viewable by diff in Edit -> Triggers (3 dots in right upper corner) -> History as well. Also important to note is that these BuildOptions are not user-specific; 5d58cc01-7c75-450c-be18-a388ddb129ec actually shows up in this extension's code base as a test case in tests/recordings/test_build_definition_listShow.yaml. Additionally, I left a comment here in a vsts-docs issue to reflect some of the observations here.

Thanks for sitting through my ted talk.

atbagga commented 4 years ago

@geverghe Not sure if this is a CLI issue. Who would be the right point of contact for the yaml pipelines triggers. The issues states that the pipelines triggers documented here does not work.

nietras commented 4 years ago

@aglorei what the status of this bug? When will it be resolved? A lot of us are getting hit by this and it causes lots of headaches 😅 cc: @mitsha-microsoft @geverghe

simongottschlag commented 3 years ago

I created the following script, but doesn't seem to be working as expected unfortunately:

#!/bin/bash

set -e

while [ ${#} -gt 0 ]; do
  case "${1}" in
    --prefix=*)
      PREFIX="${1#*=}"
      ;;
    *)
      echo "ERROR - Invalid argument: ${1}"
      exit 1
  esac
  shift
done

# Create patch json: https://github.com/Azure/azure-devops-cli-extension/issues/953
set +e
read -r -d '' JSON_PATCH << EOL
{
    "jobCancelTimeoutInMinutes": 5,
    "options": [
        {
            "definition": {
                "id": "5d58cc01-7c75-450c-be18-a388ddb129ec"
            },
            "enabled": false,
            "inputs": {
                "additionalFields": "{}",
                "branchFilters": "[\"+refs/heads/*\"]"
            }
        },
        {
            "definition": {
                "id": "a9db38f9-9fdc-478c-b0f9-464221e58316"
            },
            "enabled": false,
            "inputs": {
                "additionalFields": "{}",
                "assignToRequestor": "true",
                "workItemType": "Issue"
            }
        },
        {
            "definition": {
                "id": "57578776-4c22-4526-aeb0-86b6da17ee9c"
            },
            "enabled": false,
            "inputs": {}
        }
    ],
    "repository": {
        "defaultBranch": "refs/heads/main",
        "properties": {
            "checkoutNestedSubmodules": "false",
            "cleanOptions": "0",
            "fetchDepth": "0",
            "gitLfsSupport": "false",
            "labelSources": "0",
            "labelSourcesFormat": "\$(build.buildNumber)",
            "reportBuildStatus": "false",
            "skipSyncSource": "false"
        }
    }
}
EOL
set -e

AZDO_PROJECT="<my project name>"

PIPELINES_FULL=$(az pipelines build definition list --project ${AZDO_PROJECT} | jq -c -r ".[] | select(.name | startswith(\"${PREFIX}\"))")
PIPELINE_FULL_CSV_ARRAY=( $(jq -rc '. | [.name, .id] | join(";")' <<< "${PIPELINES_FULL}") )
declare -a PIPELINE_CSV_ARRAY=()
for PIPELINE_CSV in "${PIPELINE_FULL_CSV_ARRAY[@]}"; do
  PIPELINE_NAME=$(awk -F';' '{print $1}' <<< $PIPELINE_CSV)
  PIPELINE_ID=$(awk -F';' '{print $2}' <<< $PIPELINE_CSV)
  DEFINITION=$(az pipelines build definition show --id ${PIPELINE_ID} | sed -r 's/\\/\\\\/g' | sed -r 's/\\\\\"/\\\"/g')
  if [[ $(echo ${DEFINITION} | jq -r '.options') == null ]]; then
    PIPELINE_CSV_ARRAY+=( "${PIPELINE_CSV}" )
  fi
done

echo "You are about to fix the following ${#PIPELINE_CSV_ARRAY[@]} pipelines(s):"
echo "-----------"
for PIPELINE_CSV in "${PIPELINE_CSV_ARRAY[@]}"; do
  echo ${PIPELINE_CSV}
done
echo "-----------"
read -p "Enter ${#PIPELINE_CSV_ARRAY[@]} to continue: " CONFIRM_FIX_COUNT

if [[ ${CONFIRM_FIX_COUNT} -eq  ${#PIPELINE_CSV_ARRAY[@]} ]]; then
  TEMP_FILE_PATCH=$(mktemp)
  echo $JSON_PATCH | jq -cr > ${TEMP_FILE_PATCH}
  for PIPELINE_CSV in "${PIPELINE_CSV_ARRAY[@]}"; do
    PIPELINE_NAME=$(awk -F';' '{print $1}' <<< $PIPELINE_CSV)
    PIPELINE_ID=$(awk -F';' '{print $2}' <<< $PIPELINE_CSV)

    # Grab current revision: https://docs.microsoft.com/en-us/rest/api/azure/devops/build/definitions/update?view=azure-devops-rest-6.1
    CURRENT_REVISION=$(az devops invoke --area build --resource definitions --route --route-parameters project=${AZDO_PROJECT} definitionId=${PIPELINE_ID} --api-version "6.1-preview" --output json)
    TEMP_FILE_CURRENT_REVISION=$(mktemp)
    echo ${CURRENT_REVISION} | sed -r 's/\\/\\\\/g' | sed -r 's/\\\\\"/\\\"/g' | jq -rc > ${TEMP_FILE_CURRENT_REVISION}

    # Merge json files: https://e.printstacktrace.blog/merging-json-files-recursively-in-the-command-line/
    TEMP_FILE_MERGED=$(mktemp)
    jq -s 'def deepmerge(a;b):
      reduce b[] as $item (a;
        reduce ($item | keys_unsorted[]) as $key (.;
          $item[$key] as $val | ($val | type) as $type | .[$key] = if ($type == "object") then
            deepmerge({}; [if .[$key] == null then {} else .[$key] end, $val])
          elif ($type == "array") then
            (.[$key] + $val | unique)
          else
            $val
          end)
        );
      deepmerge({}; .)' ${TEMP_FILE_PATCH} ${TEMP_FILE_CURRENT_REVISION} > ${TEMP_FILE_MERGED}

    # Update the pipeline
    echo "Fixing pipeline: ${PIPELINE_NAME} (${PIPELINE_ID})"
    set +e
    az devops invoke --area build --resource definitions --route --route-parameters project=${AZDO_PROJECT} definitionId=${PIPELINE_ID} --api-version "6.1-preview" --in-file ${TEMP_FILE_MERGED} --http-method put 1>/dev/null
    set -e

    rm ${TEMP_FILE_CURRENT_REVISION}
    rm ${TEMP_FILE_MERGED}
  done
  rm ${TEMP_FILE_PATCH}
else
  echo "Expected input was ${#PIPELINE_CSV_ARRAY[@]} but got: ${CONFIRM_FIX_COUNT}"
  exit 1
fi