Jira writeback integration
This commit is contained in:
parent
a421bf213e
commit
e7284d4434
2 changed files with 578 additions and 0 deletions
434
azure-pipelines-automated-testing.yml
Normal file
434
azure-pipelines-automated-testing.yml
Normal file
|
|
@ -0,0 +1,434 @@
|
|||
trigger:
|
||||
branches:
|
||||
include: [ develop, release/* ]
|
||||
paths:
|
||||
exclude:
|
||||
- deployment/*
|
||||
include:
|
||||
- "*"
|
||||
pr:
|
||||
branches:
|
||||
include: [ '*' ]
|
||||
paths:
|
||||
exclude:
|
||||
- deployment/*
|
||||
include:
|
||||
- "*"
|
||||
|
||||
resources:
|
||||
containers:
|
||||
- container: node
|
||||
image: packagerepository.sagaws.net:8082/safelite/node-build:18
|
||||
- container: awscli
|
||||
image: packagerepository.sagaws.net:8082/safelite/awscli2-build:3.9
|
||||
repositories:
|
||||
- repository: AzureDevOps
|
||||
type: github
|
||||
name: Safelite/AzureDevOps
|
||||
endpoint: Safelite
|
||||
ref: refs/tags/t5.5.40
|
||||
|
||||
variables:
|
||||
- group: Digital-Infrastructure
|
||||
- group: ISS-BuildBranches
|
||||
- name: dockerImageName
|
||||
value: 'playwright-tests'
|
||||
- name: imageTag
|
||||
value: '$(Build.BuildId)'
|
||||
- name: totalShards
|
||||
value: 40 # TODO: Temporarily changed to 40, change back to 4
|
||||
|
||||
stages:
|
||||
# PR's
|
||||
- ${{ if or(eq(variables['Build.Reason'], 'PullRequest'), eq(1,1)) }}: # TODO: Temporarily changed to always be true, change back
|
||||
- stage: TestPr
|
||||
displayName: Run Tests For PullRequest
|
||||
jobs:
|
||||
- template: templates/digital/vue-jest-run-unit-tests.yml@AzureDevOps
|
||||
parameters:
|
||||
nodeContainer: node
|
||||
npmLocation: $(Build.SourcesDirectory)
|
||||
testResultsFile: junit.xml
|
||||
summaryFileLocation: $(Build.SourcesDirectory)/coverage/cobertura-coverage.xml
|
||||
- job: playwright_tests
|
||||
continueOnError: true
|
||||
strategy:
|
||||
matrix:
|
||||
shard1:
|
||||
shardNumber: 1
|
||||
shard2:
|
||||
shardNumber: 2
|
||||
shard3:
|
||||
shardNumber: 3
|
||||
shard4:
|
||||
shardNumber: 4
|
||||
|
||||
steps:
|
||||
- task: Docker@2
|
||||
displayName: 'Build Docker Image'
|
||||
inputs:
|
||||
command: build
|
||||
dockerfile: Dockerfile.playwright
|
||||
repository: $(dockerImageName)
|
||||
tags: $(imageTag)
|
||||
arguments: '--no-cache --pull'
|
||||
|
||||
- script: |
|
||||
# Create container and run tests
|
||||
container_id=$(docker create \
|
||||
--ipc=host \
|
||||
-e CCIS_API_AUTH=$(CCIS_API_AUTH) \
|
||||
-e BASE_URL=$(BASE_URL) \
|
||||
-e CCIS_API_URL=$(CCIS_API_URL) \
|
||||
-e ADMIN_SERVICE_API_URL=$(ADMIN_SERVICE_API_URL) \
|
||||
-e SHARD=$(shardNumber) \
|
||||
-e CI=true \
|
||||
-e NODE_ENV=$(NODE_ENV) \
|
||||
$(dockerImageName):$(imageTag) \
|
||||
npx concurrently -k -n "server,playwright"\
|
||||
"sed -i \"s|^process\.env\.VUE_APP_CONSUMER_CF_DISTRO = .*|process\.env\.VUE_APP_CONSUMER_CF_DISTRO='https://digitalapi.test.safelite.io'|\" \"./vue.config.js\" && echo \"Updated config file to use TEST APIs\" && npm run serve -- --port=8080"\
|
||||
"npx wait-on http://localhost:8080 && npm run test:playwright -- --shard=$(shardNumber)/$(totalShards) --reporter=list,blob --grep \"@smoke | @Advanced\"")
|
||||
|
||||
# Start container and stream logs
|
||||
|
||||
echo "Starting tests for shard $(shardNumber)..."
|
||||
docker start -a $container_id
|
||||
|
||||
# Create directory for test results
|
||||
echo "Creating test results directory..."
|
||||
mkdir -p $(System.DefaultWorkingDirectory)/blob-reports/shard-$(shardNumber)
|
||||
|
||||
# Copy test results from container
|
||||
echo "Copying test results..."
|
||||
docker cp $container_id:/app/blob-report/. $(System.DefaultWorkingDirectory)/blob-reports/shard-$(shardNumber)/
|
||||
|
||||
# Remove container
|
||||
echo "Cleaning up container..."
|
||||
docker rm $container_id
|
||||
|
||||
# Check if tests failed
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Tests failed in shard $(shardNumber)!"
|
||||
exit 1
|
||||
fi
|
||||
displayName: 'Run Playwright Tests - Shard $(shardNumber)'
|
||||
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: 'Publish Test Reports - Shard $(shardNumber)'
|
||||
condition: always()
|
||||
inputs:
|
||||
targetPath: '$(System.DefaultWorkingDirectory)/blob-reports/shard-$(shardNumber)'
|
||||
artifact: 'playwright-report-shard-$(shardNumber)'
|
||||
publishLocation: 'pipeline'
|
||||
|
||||
- script: |
|
||||
docker rmi $(dockerImageName):$(imageTag) -f
|
||||
displayName: 'Cleanup Docker Image'
|
||||
condition: always()
|
||||
|
||||
- job: download_and_merge_reports
|
||||
container:
|
||||
image: mcr.microsoft.com/playwright:v1.48.0-noble
|
||||
dependsOn: playwright_tests
|
||||
steps:
|
||||
- task: DownloadPipelineArtifact@2
|
||||
inputs:
|
||||
targetPath: '$(System.DefaultWorkingDirectory)/playwright-reports'
|
||||
- script: |
|
||||
npm i ortoni-report &&
|
||||
for dir in $(System.DefaultWorkingDirectory)/playwright-reports/*/; do
|
||||
if [ -d "$dir" ]; then
|
||||
mv "$dir"* $(System.DefaultWorkingDirectory)/playwright-reports/
|
||||
rmdir "$dir"
|
||||
fi
|
||||
done
|
||||
npx playwright merge-reports --reporter=ortoni-report,junit $(System.DefaultWorkingDirectory)/playwright-reports
|
||||
ls
|
||||
displayName: merge_reports
|
||||
env:
|
||||
PLAYWRIGHT_JUNIT_OUTPUT_FILE: "test-results/results.xml"
|
||||
- script: |
|
||||
$(System.DefaultWorkingDirectory)/jira_writeback.sh
|
||||
add_comment() $(Build.SourceBranchName) "AUTOMATED TEST RUN: $(date)" $(System.DefaultWorkingDirectory)/ortoni-report/index.html
|
||||
displayName: publish_results_to_jira
|
||||
env:
|
||||
JIRA_API_KEY: $(JIRA_API_KEY)
|
||||
|
||||
# TODO: Enable later when working on PR gate
|
||||
# - task: PublishTestResults@2
|
||||
# displayName: 'Publish test results'
|
||||
# inputs:
|
||||
# searchFolder: 'test-results'
|
||||
# testResultsFormat: 'JUnit'
|
||||
# testResultsFiles: 'results.xml'
|
||||
# mergeTestResults: true
|
||||
# failTaskOnFailedTests: false
|
||||
# testRunTitle: 'Playwright Tests'
|
||||
# condition: succeededOrFailed()
|
||||
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: 'Publish Merged Report'
|
||||
condition: always()
|
||||
inputs:
|
||||
targetPath: '$(System.DefaultWorkingDirectory)/ortoni-report'
|
||||
artifact: 'playwright-merged-report'
|
||||
publishLocation: 'pipeline'
|
||||
|
||||
- ${{ else }}:
|
||||
# Dev Build/Deploy
|
||||
- stage: Dev
|
||||
condition: eq(variables['Build.SourceBranch'], variables['dev-branch'] )
|
||||
variables:
|
||||
- group: ISS-Dev
|
||||
jobs:
|
||||
- deployment: devBuildDeployment
|
||||
displayName: Build and Deploy ISS - Dev
|
||||
environment: digitalCloud-dev
|
||||
container: node
|
||||
workspace:
|
||||
clean: all
|
||||
strategy:
|
||||
runOnce:
|
||||
deploy:
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
- task: CopyFiles@2
|
||||
inputs:
|
||||
SourceFolder: 'public/apple-pay/dev'
|
||||
Contents: '**'
|
||||
TargetFolder: 'public/.well-known'
|
||||
CleanTargetFolder: true
|
||||
- task: DeleteFiles@1
|
||||
inputs:
|
||||
SourceFolder: 'public/apple-pay'
|
||||
Contents: '**'
|
||||
RemoveSourceFolder: true
|
||||
- template: templates/digital/step-build-vue.yml@AzureDevOps
|
||||
parameters:
|
||||
buildOutputDir: dist
|
||||
environment: Dev
|
||||
- template: templates/digital/step-deploy-vue.yml@AzureDevOps
|
||||
parameters:
|
||||
artifactName: vueDistDev
|
||||
awsProfile: $(devDeploymentProfile)
|
||||
deployBuckets:
|
||||
safelite-dev-iss-us-east-2:
|
||||
clearFolder: true
|
||||
deployFolder: ''
|
||||
region: us-east-2
|
||||
safelite-dev-iss-us-east-1:
|
||||
clearFolder: true
|
||||
deployFolder: ''
|
||||
region: us-east-1
|
||||
appDeployVariables:
|
||||
__VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__)
|
||||
__VUE_APP_CURRENT_ENVIRONMENT__: $(__VUE_APP_CURRENT_ENVIRONMENT__)
|
||||
__VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__)
|
||||
__VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__)
|
||||
__VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__)
|
||||
indexDeployVariables:
|
||||
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
|
||||
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
|
||||
__VUE_APP_GOOGLE_MAPS_API_SCRIPT__: $(__VUE_APP_GOOGLE_MAPS_API_SCRIPT__)
|
||||
- template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps
|
||||
parameters:
|
||||
awsCliContainer: awscli
|
||||
distributionId: $(cfDistributionId)
|
||||
paths: /*
|
||||
awsProfile: $(devDeploymentProfile)
|
||||
|
||||
# Test Build/Deploy
|
||||
- stage: Test
|
||||
condition: eq(variables['Build.SourceBranch'], variables['test-branch'] )
|
||||
variables:
|
||||
- group: ISS-Test
|
||||
jobs:
|
||||
- deployment: testBuildDeployment
|
||||
displayName: Build and Deploy ISS - Test
|
||||
environment: NoApproval-All
|
||||
container: node
|
||||
workspace:
|
||||
clean: all
|
||||
strategy:
|
||||
runOnce:
|
||||
deploy:
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
- task: CopyFiles@2
|
||||
inputs:
|
||||
SourceFolder: 'public/apple-pay/test'
|
||||
Contents: '**'
|
||||
TargetFolder: 'public/.well-known'
|
||||
CleanTargetFolder: true
|
||||
- task: DeleteFiles@1
|
||||
inputs:
|
||||
SourceFolder: 'public/apple-pay'
|
||||
Contents: '**'
|
||||
RemoveSourceFolder: true
|
||||
- template: templates/digital/step-build-vue.yml@AzureDevOps
|
||||
parameters:
|
||||
buildOutputDir: dist
|
||||
environment: Test
|
||||
- template: templates/digital/step-deploy-vue.yml@AzureDevOps
|
||||
parameters:
|
||||
artifactName: vueDistTest
|
||||
awsProfile: $(sysDeploymentProfile)
|
||||
deployBuckets:
|
||||
safelite-sys-iss-us-east-1:
|
||||
clearFolder: true
|
||||
deployFolder: ""
|
||||
region: us-east-1
|
||||
safelite-sys-iss-us-east-2:
|
||||
clearFolder: true
|
||||
deployFolder: ""
|
||||
region: us-east-2
|
||||
appDeployVariables:
|
||||
__VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__)
|
||||
__VUE_APP_CURRENT_ENVIRONMENT__: $(__VUE_APP_CURRENT_ENVIRONMENT__)
|
||||
__VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__)
|
||||
__VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__)
|
||||
__VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__)
|
||||
indexDeployVariables:
|
||||
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
|
||||
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
|
||||
__VUE_APP_GOOGLE_MAPS_API_SCRIPT__: $(__VUE_APP_GOOGLE_MAPS_API_SCRIPT__)
|
||||
- template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps
|
||||
parameters:
|
||||
awsCliContainer: awscli
|
||||
distributionId: $(cfDistributionId)
|
||||
paths: /*
|
||||
awsProfile: $(sysDeploymentProfile)
|
||||
|
||||
# QA Build/Deploy
|
||||
- stage: QA
|
||||
condition: eq(variables['Build.SourceBranch'], variables['qa-branch'] )
|
||||
variables:
|
||||
- group: ISS-QA
|
||||
jobs:
|
||||
- deployment: qaBuildDeployment
|
||||
displayName: Build and Deploy ISS - QA
|
||||
environment: NoApproval-All
|
||||
container: node
|
||||
workspace:
|
||||
clean: all
|
||||
strategy:
|
||||
runOnce:
|
||||
deploy:
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
- task: CopyFiles@2
|
||||
inputs:
|
||||
SourceFolder: 'public/apple-pay/qa'
|
||||
Contents: '**'
|
||||
TargetFolder: 'public/.well-known'
|
||||
CleanTargetFolder: true
|
||||
- task: DeleteFiles@1
|
||||
inputs:
|
||||
SourceFolder: 'public/apple-pay'
|
||||
Contents: '**'
|
||||
RemoveSourceFolder: true
|
||||
- template: templates/digital/step-build-vue.yml@AzureDevOps
|
||||
parameters:
|
||||
buildOutputDir: dist
|
||||
environment: Qa
|
||||
- template: templates/digital/step-deploy-vue.yml@AzureDevOps
|
||||
parameters:
|
||||
artifactName: vueDistQa
|
||||
awsProfile: $(qaDeploymentProfile)
|
||||
deployBuckets:
|
||||
safelite-qa-iss-us-east-1:
|
||||
clearFolder: true
|
||||
deployFolder: ""
|
||||
region: us-east-1
|
||||
safelite-qa-iss-us-east-2:
|
||||
clearFolder: true
|
||||
deployFolder: ""
|
||||
region: us-east-2
|
||||
appDeployVariables:
|
||||
__VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__)
|
||||
__VUE_APP_CURRENT_ENVIRONMENT__: $(__VUE_APP_CURRENT_ENVIRONMENT__)
|
||||
__VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__)
|
||||
__VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__)
|
||||
__VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__)
|
||||
indexDeployVariables:
|
||||
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
|
||||
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
|
||||
__VUE_APP_GOOGLE_MAPS_API_SCRIPT__: $(__VUE_APP_GOOGLE_MAPS_API_SCRIPT__)
|
||||
- template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps
|
||||
parameters:
|
||||
awsCliContainer: awscli
|
||||
distributionId: $(cfDistributionId)
|
||||
paths: /*
|
||||
awsProfile: $(qaDeploymentProfile)
|
||||
|
||||
# Prod Build/Deploy
|
||||
- stage: Prod
|
||||
condition: succeeded('QA')
|
||||
variables:
|
||||
- group: ISS-Prod
|
||||
jobs:
|
||||
- deployment: prodBuildDeployment
|
||||
displayName: Build and Deploy ISS - Prod
|
||||
environment: digitalCloud-prod
|
||||
container: node
|
||||
workspace:
|
||||
clean: all
|
||||
strategy:
|
||||
runOnce:
|
||||
deploy:
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
- task: CopyFiles@2
|
||||
inputs:
|
||||
SourceFolder: 'public/apple-pay/prod'
|
||||
Contents: '**'
|
||||
TargetFolder: 'public/.well-known'
|
||||
CleanTargetFolder: true
|
||||
- task: DeleteFiles@1
|
||||
inputs:
|
||||
SourceFolder: 'public/apple-pay'
|
||||
Contents: '**'
|
||||
RemoveSourceFolder: true
|
||||
- template: templates/digital/step-build-vue.yml@AzureDevOps
|
||||
parameters:
|
||||
buildOutputDir: dist
|
||||
environment: Prod
|
||||
- template: templates/digital/step-deploy-vue.yml@AzureDevOps
|
||||
parameters:
|
||||
artifactName: vueDistProd
|
||||
awsProfile: $(prodDeploymentProfile)
|
||||
deployBuckets:
|
||||
safelite-prod-iss-us-east-1:
|
||||
clearFolder: true
|
||||
deployFolder: ""
|
||||
region: us-east-1
|
||||
safelite-prod-iss-us-east-2:
|
||||
clearFolder: true
|
||||
deployFolder: ""
|
||||
region: us-east-2
|
||||
appDeployVariables:
|
||||
__VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__)
|
||||
__VUE_APP_CURRENT_ENVIRONMENT__: $(__VUE_APP_CURRENT_ENVIRONMENT__)
|
||||
__VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__)
|
||||
__VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__)
|
||||
__VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__)
|
||||
indexDeployVariables:
|
||||
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
|
||||
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
|
||||
__VUE_APP_GOOGLE_MAPS_API_SCRIPT__: $(__VUE_APP_GOOGLE_MAPS_API_SCRIPT__)
|
||||
- template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps
|
||||
parameters:
|
||||
awsCliContainer: awscli
|
||||
distributionId: $(cfDistributionId)
|
||||
paths: /*
|
||||
awsProfile: $(prodDeploymentProfile)
|
||||
- template: templates/digital/auto-tag.yml@AzureDevOps
|
||||
parameters:
|
||||
dependsOn: prodBuildDeployment
|
||||
userName: SafeliteAzureDevops
|
||||
userEmail: githubazuredevops@safelite.com
|
||||
|
||||
144
devops/scripts/jira_writeback.sh
Executable file
144
devops/scripts/jira_writeback.sh
Executable file
|
|
@ -0,0 +1,144 @@
|
|||
create_issue() {
|
||||
local title="$1"
|
||||
local project_key="$2"
|
||||
local issue_type="$3"
|
||||
local parent_issue_key="$4"
|
||||
|
||||
AUTH=$(echo -ne "$JIRA_USERNAME:$JIRA_API_KEY" | base64 --wrap 0)
|
||||
|
||||
local parent_issue=$(curl -s -H "Authorization: Basic $AUTH" \
|
||||
"$JIRA_SERVER/rest/api/3/issue/$parent_issue_key")
|
||||
|
||||
local parent_fix_versions=$(echo $parent_issue | jq -r '.fields.fixVersions')
|
||||
|
||||
local created_issue=$(curl -X POST -H "Content-Type: application/json" \
|
||||
-H "Authorization: Basic $AUTH" \
|
||||
-d '{
|
||||
"fields": {
|
||||
"summary": "'"$title"'",
|
||||
"project": {
|
||||
"key": "'"$project_key"'"
|
||||
},
|
||||
"issuetype": {
|
||||
"name": "'"$issue_type"'"
|
||||
},
|
||||
"parent": {
|
||||
"key": "'"$parent_issue_key"'"
|
||||
},
|
||||
"fixVersions": '"$parent_fix_versions"'
|
||||
}
|
||||
}' \
|
||||
"$JIRA_SERVER/rest/api/3/issue")
|
||||
|
||||
local created_issue_id=$(echo $created_issue | jq -r '.id')
|
||||
|
||||
curl -X PUT -H "Content-Type: application/json" \
|
||||
-H "Authorization: Basic $AUTH" \
|
||||
-d '{
|
||||
"fields": {
|
||||
"fixVersions": '"$parent_fix_versions"'
|
||||
}
|
||||
}' \
|
||||
"$JIRA_SERVER/rest/api/3/issue/$created_issue_id"
|
||||
}
|
||||
|
||||
extract_uuid() {
|
||||
local url="$1"
|
||||
local uuid_regex='[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}'
|
||||
if [[ "$url" =~ $uuid_regex ]]; then
|
||||
echo "${BASH_REMATCH}"
|
||||
else
|
||||
echo "No UUID found in the URL."
|
||||
fi
|
||||
}
|
||||
|
||||
update_issue_status() {
|
||||
local issue_key="$1"
|
||||
local status_name="$2"
|
||||
|
||||
AUTH=$(echo -ne "$JIRA_USERNAME:$JIRA_API_KEY" | base64 --wrap 0)
|
||||
|
||||
local transitions=$(curl -s -H "Authorization: Basic $AUTH" \
|
||||
"$JIRA_SERVER/rest/api/3/issue/$issue_key/transitions")
|
||||
|
||||
local transition_id=$(echo "$transitions" | jq -r --arg status_name "$status_name" '
|
||||
.transitions[] | select(.isAvailable == true and .to.name == $status_name) | .id
|
||||
')
|
||||
|
||||
if [ -z "$transition_id" ]; then
|
||||
echo "BadRequestError"
|
||||
exit 1
|
||||
else
|
||||
curl -X POST -H "Content-Type: application/json" \
|
||||
-H "Authorization: Basic $AUTH" \
|
||||
-d '{
|
||||
"transition": {
|
||||
"id": "'"$transition_id"'"
|
||||
}
|
||||
}' \
|
||||
"$JIRA_SERVER/rest/api/3/issue/$issue_key/transitions"
|
||||
fi
|
||||
}
|
||||
|
||||
add_attachments() {
|
||||
AUTH=$(echo -ne "$JIRA_USERNAME:$JIRA_API_KEY" | base64 --wrap 0)
|
||||
|
||||
local issue_key="$1"
|
||||
shift
|
||||
local attachments=("$@")
|
||||
|
||||
echo $issue_key
|
||||
echo $attachments
|
||||
|
||||
local form_data=""
|
||||
for attachment in "${attachments[@]}"; do
|
||||
form_data+="--form file=@$attachment "
|
||||
done
|
||||
|
||||
echo $form_data
|
||||
|
||||
echo $(curl -X POST $form_data \
|
||||
-H "X-Atlassian-Token: no-check" \
|
||||
-H "Authorization: Basic $AUTH" \
|
||||
"$JIRA_SERVER/rest/api/3/issue/$issue_key/attachments")
|
||||
}
|
||||
|
||||
add_comment() {
|
||||
AUTH=$(echo -ne "$JIRA_USERNAME:$JIRA_API_KEY" | base64 --wrap 0)
|
||||
local issue_key="$1"
|
||||
shift
|
||||
local comment_items_input=("$@")
|
||||
local comment_json="[]"
|
||||
|
||||
for item in "${comment_items_input[@]}"; do
|
||||
if [ -e "$item" ]; then
|
||||
# If it's a file path
|
||||
local attachment=$(add_attachments "$issue_key" "$item")
|
||||
local id=$(echo $attachment | grep -oP '"id":\s*"\K[^"]+')
|
||||
|
||||
local attachment_content=$(curl -s -I -L -H "Authorization: Basic $AUTH" "$JIRA_SERVER/rest/api/3/attachment/content/$id" \
|
||||
| grep -i "Location:" | tail -1 | awk '{print $2}' | tr -d '\r')
|
||||
echo "$JIRA_SERVER/rest/api/3/attachment/content/$id"
|
||||
echo "$attachment_content"
|
||||
|
||||
local uuid=$(extract_uuid "$attachment_content")
|
||||
echo "$uuid"
|
||||
|
||||
json_object=$(jq -n --arg uuid "$uuid" '{ type: "mediaSingle", attrs: { layout: "align-start" }, content: [{ type: "media", attrs: { type: "file", id: $uuid, width: 200, height: 200, collection: "", alt: "" } }]}')
|
||||
|
||||
comment_json=$(echo "$comment_json" | jq --argjson obj "$json_object" '. += [$obj]')
|
||||
else
|
||||
# If it's a string
|
||||
json_object=$(jq -n --arg text "$item" '{ type: "paragraph", content: [{ type: "text", text: $text }]}')
|
||||
|
||||
comment_json=$(echo "$comment_json" | jq --argjson obj "$json_object" '. += [$obj]')
|
||||
fi
|
||||
done
|
||||
|
||||
request=$(jq -n --argjson content "$comment_json" '{body: { type: "doc", version: 1, content: $content }}')
|
||||
|
||||
curl -X POST -H "Content-Type: application/json" \
|
||||
-H "Authorization: Basic $AUTH" \
|
||||
-d "$request" \
|
||||
"$JIRA_SERVER/rest/api/3/issue/$issue_key/comment"
|
||||
}
|
||||
Loading…
Reference in a new issue