mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-04-20 07:25:51 -04:00
ci: add action to create issues in projects
Signed-off-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
This commit is contained in:
parent
648eebab24
commit
acb972478f
64
.github/actions/gh_create_issue/action.yml
vendored
Normal file
64
.github/actions/gh_create_issue/action.yml
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
name: Create a GitHub issue
|
||||
description: "Create an issue on GitHub, and optionally add it to a project board."
|
||||
|
||||
inputs:
|
||||
title:
|
||||
description: "The title of the issue."
|
||||
required: true
|
||||
owner:
|
||||
description: "The owner of the repository to create the issue in."
|
||||
required: false
|
||||
default: ${{ github.repository_owner }}
|
||||
repo:
|
||||
description: "The repository to create the issue in."
|
||||
required: false
|
||||
default: ${{ github.repository }}
|
||||
token:
|
||||
description: "The GitHub token to use to authenticate."
|
||||
required: false
|
||||
default: ${{ github.token }}
|
||||
body:
|
||||
description: "The body of the issue."
|
||||
required: false
|
||||
body-file:
|
||||
description: "The path to a file containing the body of the issue."
|
||||
required: false
|
||||
assignee:
|
||||
description: "The GitHub username to assign the issue to."
|
||||
required: false
|
||||
labels:
|
||||
description: "A comma-separated list of labels to add to the issue."
|
||||
required: false
|
||||
milestone:
|
||||
description: "The milestone to add the issue to."
|
||||
required: false
|
||||
project:
|
||||
description: "Number of the project to add the issue to."
|
||||
required: false
|
||||
template:
|
||||
description: "The template to use for the issue."
|
||||
required: false
|
||||
fields:
|
||||
description: "A JSON object containing the fields to use for the issue."
|
||||
required: false
|
||||
|
||||
outputs:
|
||||
issue-url:
|
||||
description: "The URL of the created issue."
|
||||
value: ${{ steps.run.outputs.issue-url }}
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Run create_issue.sh
|
||||
id: run
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{ inputs.token }}
|
||||
run: |
|
||||
set -x
|
||||
cat << EOF | tee inputs.json
|
||||
${{ toJSON(inputs) }}
|
||||
EOF
|
||||
out=$(./.github/actions/gh_create_issue/create_issue.sh inputs.json)
|
||||
echo "issue-url=${out}" | tee -a "$GITHUB_OUTPUT"
|
248
.github/actions/gh_create_issue/create_issue.sh
vendored
Executable file
248
.github/actions/gh_create_issue/create_issue.sh
vendored
Executable file
@ -0,0 +1,248 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
set -x
|
||||
|
||||
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}"
|
||||
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 "${@}"
|
Loading…
x
Reference in New Issue
Block a user