salesforcecli / plugin-devops-center

The DevOps Center CLI plugin provides a command-line alternative to performing equivalent actions in the DevOps Center graphical UI
BSD 3-Clause "New" or "Revised" License
9 stars 4 forks source link

Create WorkItem from CLI #433

Open Damecek opened 1 month ago

Damecek commented 1 month ago

It can be cumbersome to go to DevOps Center to create new Work Item. It takes time and a lot of clicks.

Describe the solution you'd like

We have automated this by creating following script, which we run from our IDE via project.json. It would be great if this script was implemented as part of the CLI. A command to create a Work Item for a specified project, with the option to create a branch automatically.

Something like this:

USAGE
  $ sf project workitem create -s <value> -c <value> -p <value> [--json] [-e <value>] [-a <value>]

FLAGS
  -s, --subject                             (required) Subject of the created Work Item.
  -c, --devops-center-username=<value>      (required) Username or alias of the DevOps Center org.
  -p, --devops-center-project-name=<value>  (required) Name of the DevOps Center project.
  -e, --development-environment=<value>     Target development environment to which the Work Item should be connected. If not provided, a feature branch will be created.
  -a, --assigned-to=<value>                 User to whom the Work Item should be assigned. Defaults to the running user.

DESCRIPTION
  Creates a new Work Item in Salesforce DevOps Center for the specified project with the given subject. Optionally, it can connect the Work Item to a specified development environment or, if not provided, automatically create a feature branch. You can assign the Work Item to a specific user using the `--assigned-to` flag; if not specified, the Work Item will be assigned to the running user. This command simplifies the process of initiating new work by reducing the need to navigate through the DevOps Center UI, saving time and streamlining your development workflow.

Example Usages with Use Cases

  1. Creating a Work Item Assigned to Yourself

    Use Case: You want to start working on a new feature and need to create a Work Item that is assigned to you.

    sf project workitem create \
     --subject "Implement OAuth2 authentication" \
     --devops-center-username myDevOpsOrg \
     --devops-center-project-name "Security Enhancements"

    Explanation: This command creates a Work Item titled "Implement OAuth2 authentication" in the "Security Enhancements" project of your DevOps Center org myDevOpsOrg. Since --assigned-to is not specified, the Work Item is assigned to you, the running user.

  2. Creating a Work Item and Assigning It to Another Team Member

    Use Case: You are a project manager assigning a bug fix to a developer on your team.

    sf project workitem create \
     --subject "Fix null pointer exception on login" \
     --devops-center-username myDevOpsOrg \
     --devops-center-project-name "Bug Fixes" \
     --assigned-to jane.doe@example.com

    Explanation: This command creates a Work Item titled "Fix null pointer exception on login" in the "Bug Fixes" project and assigns it to jane.doe@example.com.

  3. Creating a Work Item Connected to a Specific Development Environment

    Use Case: You want the Work Item to be connected to a particular development environment instead of creating a new feature branch.

    sf project workitem create \
     --subject "Update API versioning strategy" \
     --devops-center-username myDevOpsOrg \
     --devops-center-project-name "API Development" \
     --development-environment "Dev Environment 2"

    Explanation: The Work Item is created and connected to "Dev Environment 2". This is useful when you have predefined development environments.

  4. Assigning a Work Item to a User and Connecting to a Development Environment

    Use Case: Assign a task to a team member and specify the development environment they should use.

    sf project workitem create \
     --subject "Optimize database queries" \
     --devops-center-username myDevOpsOrg \
     --devops-center-project-name "Performance Improvements" \
     --assigned-to alex.smith@example.com \
     --development-environment "Performance Lab"

    Explanation: This command assigns the Work Item to alex.smith@example.com and connects it to the "Performance Lab" environment.

Additional context

#!/bin/bash

# This script is designed to create a Work Item record in Salesforce and output the URL of the created record.
# It is intended to be used in the context of Salesforce DevOps processes.
#
# Requirements:
# 1. Salesforce CLI (sf) must be installed and configured on the machine where this script is run.
# 2. The user must be authenticated in Salesforce CLI and have necessary permissions to create records and retrieve user information.
# 3. jq (a lightweight and flexible command-line JSON processor) must be installed.
# 4. A .env file must be present in the project root directory, containing the necessary environment variables.
#    Specifically, SF_PROD_ORG must be set to the Salesforce production organization's alias or login URL.
#
# Usage:
# npm run create-workitem [SUBJECT]
# - SUBJECT: (Optional) The subject of the Work Item to be created. If not provided, the script will prompt the user to enter it.

# Source .env file
set -a
source .env
set +a

# Check if SF_PROD_ORG is set
if [[ -z $SF_PROD_ORG ]]; then
  echo "Error: The SF_PROD_ORG environment variable is not set."
  echo "Please set this variable in your .env file or in your current session and run the script again."
  exit 1
fi

# Check if PROJECT_ID is set
if [[ -z $PROJECT_ID ]]; then
  echo "Error: The PROJECT_ID environment variable is not set."
  echo "Please set this variable in your .env file or in your current session and run the script again."
  exit 1
fi

# Set SF_TARGET_ORG to the value of SF_PROD_ORG
export SF_TARGET_ORG=$SF_PROD_ORG
export SF_CONTENT_TYPE="JSON"

# Check if the SUBJECT argument is supplied, if not, prompt the user for input
if [[ -z $1 ]]; then
  read -p "Please enter the SUBJECT: " SUBJECT
else
  SUBJECT=$1
fi

# Get the current user's ID
CURRENT_USER_ID=$(sf org display user | jq -r '.result.id')

# Check if the user ID was successfully retrieved
if [[ -z $CURRENT_USER_ID ]]; then
  echo "Error: Could not retrieve the current user's ID. Please make sure you are authenticated in Salesforce CLI."
  exit 1
fi

# Create the record and capture the ID
WORK_ITEM_ID=$(sf data record create -s sf_devops__Work_Item__c -v "sf_devops__Assigned_To__c='$CURRENT_USER_ID' sf_devops__Project__c='$PROJECT_ID' sf_devops__Subject__c='$SUBJECT'" | jq -r '.result.id')

# Check if the record was successfully created
if [[ -z $WORK_ITEM_ID ]]; then
  echo "Error: Could not create the Work Item record."
  exit 1
fi

# Query for the Name of the created Work Item
WORK_ITEM_NAME=$(sf data query -q "SELECT Name FROM sf_devops__Work_Item__c WHERE Id = '$WORK_ITEM_ID'" | jq -r '.result.records[0].Name')

# Get the Salesforce instance URL for the production org
PROD_URL=$(sf org display --target-org "$SF_PROD_ORG" | jq -r '.result.instanceUrl')

# Check if the instance URL was successfully retrieved
if [[ -z $PROD_URL ]]; then
  echo "Error: Could not retrieve the Salesforce instance URL. Please make sure your org is correctly configured."
  exit 1
fi

# Output the Work Item details
echo "Work Item Created Successfully!"
echo "---------------------------------"
echo "Work Item Name: $WORK_ITEM_NAME"
echo "Work Item URL: $PROD_URL/sf_devops/DevOpsCenter.app?workItemId=$WORK_ITEM_ID"
echo "---------------------------------"

# Query to get the branch name (xxx) where sf_devops__Pipeline_Stages__r is null
BRANCH_NAME=$(sf data query -q "SELECT sf_devops__Branch__r.sf_devops__Name__c, ( SELECT Id FROM sf_devops__Pipeline_Stages__r ) FROM sf_devops__Pipeline_Stage__c WHERE sf_devops__Pipeline__r.sf_devops__Project__c = '$PROJECT_ID'" | jq -r '.result.records[] | select(.sf_devops__Pipeline_Stages__r == null) | .sf_devops__Branch__r.sf_devops__Name__c')

# Check if the branch name was successfully retrieved
if [[ -z $BRANCH_NAME ]]; then
  echo "Error: Could not retrieve the branch name. Please make sure the query is correct."
  exit 1
fi

# Checkout the base branch (xxx)
git fetch origin "$BRANCH_NAME" --quiet
git checkout "$BRANCH_NAME" --quiet

# Check if the checkout was successful
if [[ $? -ne 0 ]]; then
  echo "Error: Could not checkout the base branch '$BRANCH_NAME'."
  exit 1
fi

# Pull the latest changes from the base branch
git pull origin "$BRANCH_NAME" -n --ff --quiet

# Create a new git branch with the Work Item name starting from the base branch
NEW_BRANCH_NAME="$WORK_ITEM_NAME"

git checkout -b "$NEW_BRANCH_NAME" --quiet

# Check if the branch was created successfully
if [[ $? -ne 0 ]]; then
  echo "Error: Could not create the new git branch '$NEW_BRANCH_NAME'."
  exit 1
fi

# Push the new branch to the remote repository
git push -u origin "$NEW_BRANCH_NAME"

# Check if the push was successful
if [[ $? -ne 0 ]]; then
  echo "Error: Could not push the new branch to the remote repository."
  exit 1
fi

echo "New git branch '$NEW_BRANCH_NAME' created and pushed successfully."

exit 0
Damecek commented 1 month ago

the branch creation is based on this article