constellation/.github/actions/gh_create_issue/create_issue.sh

255 lines
5.1 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
set -euo pipefail
function debug() {
echo "DEBUG: $*" >&2
}
function warn() {
echo "WARN: $*" >&2
}
function inputs() {
name="${1}"
local val
val=$(jq -r ".\"${name}\"" "${inputFile}")
if [[ ${val} == "null" ]]; then
warn "Input ${name} not found in ${inputFile}"
return
fi
echo "${val}"
}
function flagsFromInput() {
flagNames=("${@}")
for name in "${flagNames[@]}"; do
val=$(inputs "${name}")
if [[ -n ${val} ]]; then
echo "--${name}=${val}"
fi
done
}
function createIssue() {
flags=(
"assignee"
"body"
"body-file"
"label"
"milestone"
"project"
"template"
"title"
)
readarray -t flags <<< "$(flagsFromInput "${flags[@]}")"
flags+=("--repo=$(inputs owner)/$(inputs repo)")
debug gh issue create "${flags[@]}"
gh issue create "${flags[@]}"
}
function listProjects() {
flags=(
"owner"
)
readarray -t flags <<< "$(flagsFromInput "${flags[@]}")"
flags+=("--format=json")
debug gh project list "${flags[@]}"
gh project list "${flags[@]}" >> projects.json
}
function findProjectID() {
project=$(inputs "project")
out="$(
jq -r \
--arg project "${project}" \
'.projects[]
| select(.title == $project)
| .id' \
projects.json
)"
debug "Project ID: ${out}"
echo "${out}"
}
function findProjectNo() {
project=$(inputs "project")
out="$(
jq -r \
--arg project "${project}" \
'.projects[]
| select(.title == $project)
| .number' \
projects.json
)"
debug "Project Number: ${out}"
echo "${out}"
}
function listItems() {
local projectNo="${1}"
flags=(
"owner"
)
readarray -t flags <<< "$(flagsFromInput "${flags[@]}")"
flags+=("--limit=1000")
flags+=("--format=json")
debug gh project item-list "${flags[@]}" "${projectNo}"
gh project item-list "${flags[@]}" "${projectNo}" >> issues.json
}
function findIssueItemID() {
local issueURL="${1}"
out="$(
jq -r \
--arg issueURL "${issueURL}" \
'.items[]
| select(.content.url == $issueURL)
| .id' \
issues.json
)"
debug "Issue Item ID: ${out}"
echo "${out}"
}
function listFields() {
local projectNo="${1}"
flags=(
"owner"
)
readarray -t flags <<< "$(flagsFromInput "${flags[@]}")"
flags+=("--limit=1000")
flags+=("--format=json")
debug gh project field-list "${flags[@]}" "${projectNo}"
gh project field-list "${flags[@]}" "${projectNo}" >> fields.json
}
function findFieldID() {
local fieldName="${1}"
out="$(
jq -r \
--arg fieldName "${fieldName}" \
'.fields[]
| select(.name == $fieldName)
| .id' \
fields.json
)"
debug "Field ID of '${fieldName}': ${out}"
echo "${out}"
}
function findSelectFieldID() {
local fieldName="${1}"
local fieldValue="${2}"
out="$(
jq -r \
--arg fieldName "${fieldName}" \
--arg fieldValue "${fieldValue}" \
'.fields[]
| select(.name == $fieldName)
| .options[]
| select(.name == $fieldValue)
| .id' \
fields.json
)"
debug "Field ID of '${fieldName}': ${out}"
echo "${out}"
}
function findFieldType() {
local fieldName="${1}"
out="$(
jq -r \
--arg fieldName "${fieldName}" \
'.fields[]
| select(.name == $fieldName)
| .type' \
fields.json
)"
debug "Field type of '${fieldName}': ${out}"
echo "${out}"
}
function editItem() {
local projectID="${1}"
local itemID="${2}"
local id="${3}"
local value="${4}"
if [[ -z ${value} ]]; then
debug skipping empty value
return
fi
flags=(
"--project-id=${projectID}"
"--id=${itemID}"
"--field-id=${id}"
"--text=${value}"
)
debug gh project item-edit "${flags[@]}"
gh project item-edit "${flags[@]}" > /dev/null
}
function setFields() {
local projectID="${1}"
local itemID="${2}"
fieldsLen="$(jq -r '.fields' "${inputFile}" | yq 'length')"
debug "Number of fields in input: ${fieldsLen}"
for ((i = 0; i < fieldsLen; i++)); do
name="$(jq -r '.fields' "${inputFile}" |
yq "to_entries | .[${i}].key")"
value="$(jq -r '.fields' "${inputFile}" |
yq "to_entries | .[${i}].value")"
debug "Field ${i}: ${name} = ${value}"
type=$(findFieldType "${name}")
case "${type}" in
"ProjectV2Field")
id=$(findFieldID "${name}")
;;
"ProjectV2SingleSelectField")
id=$(findSelectFieldID "${name}" "${value}")
;;
*)
warn "Unknown field type: ${type}"
return 1
;;
esac
editItem "${projectID}" "${itemID}" "${id}" "${value}"
done
}
function main() {
inputFile="$(realpath "${1}")"
workdir=$(mktemp -d)
pushd "${workdir}" > /dev/null
trap 'debug "not cleaning up, working directory at: ${workdir}"' ERR
issueURL=$(createIssue)
echo "${issueURL}"
project=$(inputs "project")
if [[ -z ${project} ]]; then
return
fi
listProjects
projectNo=$(findProjectNo)
projectID=$(findProjectID)
listItems "${projectNo}"
issueItemID=$(findIssueItemID "${issueURL}")
listFields "${projectNo}"
setFields "${projectID}" "${issueItemID}"
popd > /dev/null
rm -rf "${workdir}"
}
main "${@}"