|
| 1 | +#!/bin/bash |
| 2 | +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin |
| 3 | + |
| 4 | +# ----------------------------------------------------------------------------- |
| 5 | +# Copyright (C) Business Learning Incorporated (businesslearninginc.com) |
| 6 | +# |
| 7 | +# This program is free software: you can redistribute it and/or modify |
| 8 | +# it under the terms of the GNU General Public License as published by |
| 9 | +# the Free Software Foundation, either version 3 of the License, or |
| 10 | +# (at your option) any later version. |
| 11 | +# |
| 12 | +# This program is distributed in the hope that it will be useful, |
| 13 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | +# GNU General Public License at <http://www.gnu.org/licenses/> for |
| 16 | +# more details. |
| 17 | +# ----------------------------------------------------------------------------- |
| 18 | +# |
| 19 | +# A bash script to POST user stories into a Taiga project |
| 20 | +# |
| 21 | +# Version: 0.1 |
| 22 | +# |
| 23 | +# Requirements: |
| 24 | +# |
| 25 | +# --Preexisting Taiga project |
| 26 | +# --Curl (http://curl.haxx.se/) must be installed on host machine |
| 27 | +# --JQ (https://stedolan.github.io/jq/) must be installed on host machine |
| 28 | +# |
| 29 | +# Inputs: |
| 30 | +# |
| 31 | +# --Website URL (e.g., http://www.website.com) |
| 32 | +# --Project slug name (NOT project name) |
| 33 | +# --Input file of user stories to import (tab-delimited) |
| 34 | +# --Username (must have appropriate admin permissions to export project) |
| 35 | +# --Password |
| 36 | +# |
| 37 | +# Outputs: |
| 38 | +# |
| 39 | +# --None: side effects are user stories imported into Taiga project |
| 40 | +# --If failure, causing error message displayed |
| 41 | +# |
| 42 | + |
| 43 | +echo " |
| 44 | +| |
| 45 | +| A bash script to POST user stories into a Taiga project |
| 46 | +| |
| 47 | +| Usage: |
| 48 | +| export_taiga [options] |
| 49 | +| |
| 50 | +| -w, --website website_url (e.g., http://www.website.com) |
| 51 | +| -n, --projectslugname project_slug_name (not the project name) |
| 52 | +| -i, --inputfile input file (CSV-format with columns: title, description, tag1, tag2, tag3) |
| 53 | +| -u, --username user_name |
| 54 | +| -p, --password password |
| 55 | +|" |
| 56 | +echo |
| 57 | + |
| 58 | +# ----------------------------------------------------------------------------- |
| 59 | +# Functions |
| 60 | +# |
| 61 | + |
| 62 | +function quit { |
| 63 | + echo |
| 64 | + exit 1 |
| 65 | +} |
| 66 | + |
| 67 | +DEBUG=false |
| 68 | + |
| 69 | +# ----------------------------------------------------------------------------- |
| 70 | +# Scan cmdline for arguments |
| 71 | +# |
| 72 | +while [[ $# -gt 0 ]] |
| 73 | +do |
| 74 | + ARG="$1" |
| 75 | + |
| 76 | + case $ARG in |
| 77 | + -w|--website) |
| 78 | + ARG_WEBSITE="$2" |
| 79 | + shift # skip argument |
| 80 | + ;; |
| 81 | + -n|--projectslugname) |
| 82 | + ARG_PROJECTSLUG="$2" |
| 83 | + shift # skip argument |
| 84 | + ;; |
| 85 | + -i|--inputfile) |
| 86 | + ARG_INPUTFILE="$2" |
| 87 | + shift # skip argument |
| 88 | + ;; |
| 89 | + -u|--username) |
| 90 | + ARG_USERNAME="$2" |
| 91 | + shift # skip argument |
| 92 | + ;; |
| 93 | + -p|--password) |
| 94 | + ARG_PASSWORD="$2" |
| 95 | + shift # skip argument |
| 96 | + ;; |
| 97 | + *) |
| 98 | + # unknown argument |
| 99 | + ;; |
| 100 | + esac |
| 101 | + shift # skip argument or value |
| 102 | +done |
| 103 | + |
| 104 | +# ----------------------------------------------------------------------------- |
| 105 | +# check for argument completeness |
| 106 | +# |
| 107 | + |
| 108 | +ARG_ERROR=false |
| 109 | + |
| 110 | +if [ -z "${ARG_WEBSITE}" ]; then |
| 111 | + echo "Error: website_url argument (-w|--website) missing." |
| 112 | + ARG_ERROR=true |
| 113 | +fi |
| 114 | + |
| 115 | +if [ -z "${ARG_PROJECTSLUG}" ]; then |
| 116 | + echo "Error: project_slug_name argument (-n|--projectslugname) missing." |
| 117 | + ARG_ERROR=true |
| 118 | +fi |
| 119 | + |
| 120 | +if [ -z "${ARG_INPUTFILE}" ]; then |
| 121 | + echo "Error: inputfile argument (-i|--inputfile) missing." |
| 122 | + ARG_ERROR=true |
| 123 | +fi |
| 124 | + |
| 125 | +if [ -z "${ARG_USERNAME}" ]; then |
| 126 | + echo "Error: user_name argument (-u|--username) missing." |
| 127 | + ARG_ERROR=true |
| 128 | +fi |
| 129 | + |
| 130 | +if [ -z "${ARG_PASSWORD}" ]; then |
| 131 | + echo "Error: password argument (-p|--password) missing." |
| 132 | + ARG_ERROR=true |
| 133 | +fi |
| 134 | + |
| 135 | +if [ "${ARG_ERROR}" = true ]; then |
| 136 | + quit |
| 137 | +fi |
| 138 | + |
| 139 | +# ----------------------------------------------------------------------------- |
| 140 | +# check requirements |
| 141 | +# |
| 142 | + |
| 143 | +REQ_ERROR=false |
| 144 | + |
| 145 | +if ! type "curl" &> /dev/null; then |
| 146 | + echo "Error: curl program not installed." |
| 147 | + REQ_ERROR=true |
| 148 | +fi |
| 149 | + |
| 150 | +if ! type "jq" &> /dev/null; then |
| 151 | + echo "Error: jq program not installed." |
| 152 | + REQ_ERROR=true |
| 153 | +fi |
| 154 | + |
| 155 | +if [ "${REQ_ERROR}" = true ]; then |
| 156 | + quit |
| 157 | +fi |
| 158 | + |
| 159 | +# ----------------------------------------------------------------------------- |
| 160 | +# Get AUTH_TOKEN |
| 161 | +# |
| 162 | +USER_AUTH_DETAIL=$( curl -X POST \ |
| 163 | + -H "Content-Type: application/json"\ |
| 164 | + -d '{ |
| 165 | + "type": "normal", |
| 166 | + "username": "'${ARG_USERNAME}'", |
| 167 | + "password": "'${ARG_PASSWORD}'" |
| 168 | + }'\ |
| 169 | + "${ARG_WEBSITE}"/api/v1/auth 2>/dev/null ) |
| 170 | + |
| 171 | +AUTH_TOKEN=$( echo "${USER_AUTH_DETAIL}" | jq -r '.auth_token' ) |
| 172 | + |
| 173 | +if [ "${DEBUG}" = true ]; then |
| 174 | + echo "AUTH_TOKEN is: ${AUTH_TOKEN}" |
| 175 | +fi |
| 176 | + |
| 177 | +# Exit if AUTH_TOKEN is not present (failed login) |
| 178 | +# |
| 179 | +if [ -z "${AUTH_TOKEN}" ]; then |
| 180 | + echo "Error: Incorrect username and/or password supplied" |
| 181 | + quit |
| 182 | +fi |
| 183 | + |
| 184 | +# ----------------------------------------------------------------------------- |
| 185 | +# Get project ID |
| 186 | +# |
| 187 | +JSON_PROJECT_ID=$( curl -X GET \ |
| 188 | + -H "Content-Type: application/json"\ |
| 189 | + -H "Authorization: Bearer ${AUTH_TOKEN}"\ |
| 190 | + "${ARG_WEBSITE}"/api/v1/resolver?project="${ARG_PROJECTSLUG}" 2>/dev/null ) |
| 191 | + |
| 192 | + |
| 193 | +PROJECT_ID=$( echo "${JSON_PROJECT_ID}" | jq -r '.project' ) |
| 194 | + |
| 195 | +if [ "${DEBUG}" = true ]; then |
| 196 | + echo "PROJECT_ID is: ${PROJECT_ID}" |
| 197 | +fi |
| 198 | + |
| 199 | +if [ -z "${PROJECT_ID}" ]; then |
| 200 | + echo "Error: Project ID not found." |
| 201 | + quit |
| 202 | +fi |
| 203 | + |
| 204 | +# ----------------------------------------------------------------------------- |
| 205 | +# POST user stories to Taiga project |
| 206 | +# |
| 207 | +# NOTE: taiga administrative permissions are required to export project file |
| 208 | +# |
| 209 | + |
| 210 | +# verify that ARG_INPUTFILE exists |
| 211 | +# |
| 212 | +if [ ! -e ${ARG_INPUTFILE} ]; then |
| 213 | + echo "Error: inputfile does not exist." |
| 214 | + quit |
| 215 | +fi |
| 216 | + |
| 217 | +# Parse tab-delimited ARG_INPUTFILE and POST stories |
| 218 | +# |
| 219 | +while IFS=$'\t' read -r FILE_TITLE FILE_DESCRIPTION FILE_TAG1 FILE_TAG2 FILE_TAG3 |
| 220 | +do |
| 221 | + |
| 222 | + if [ "${DEBUG}" = true ]; then |
| 223 | + echo "Line parsed: ${FILE_TITLE} || ${FILE_DESCRIPTION} || ${FILE_TAG1} || ${FILE_TAG2} || ${FILE_TAG3}" |
| 224 | + fi |
| 225 | + |
| 226 | + STORY_POST=$( curl -X POST \ |
| 227 | + -H "Content-Type: application/json" \ |
| 228 | + -H "Authorization: Bearer ${AUTH_TOKEN}" \ |
| 229 | + -d '{ |
| 230 | + "project": '${PROJECT_ID}', |
| 231 | + "subject": "'"${FILE_TITLE}"'", |
| 232 | + "description": "'"${FILE_DESCRIPTION}"'", |
| 233 | + "tags": [ |
| 234 | + "'"${FILE_TAG1}"'", |
| 235 | + "'"${FILE_TAG2}"'", |
| 236 | + "'"${FILE_TAG3}"'" |
| 237 | + ] |
| 238 | + }' \ |
| 239 | + "${ARG_WEBSITE}"/api/v1/userstories 2>/dev/null ) |
| 240 | + |
| 241 | + STORY_RESULT=$( echo "${STORY_POST}" | jq -r '.description' ) |
| 242 | + STORY_ID=$( echo "${STORY_POST}" | jq -r '.id' ) |
| 243 | + |
| 244 | + if [ "${DEBUG}" = true ]; then |
| 245 | + echo "STORY_RESULT is: ${STORY_RESULT}" |
| 246 | + fi |
| 247 | + |
| 248 | + if [ -z "${STORY_RESULT}" ]; then |
| 249 | + echo "Error: user story NOT imported." |
| 250 | + quit |
| 251 | + else |
| 252 | + echo "Success: user story #${STORY_ID} imported." |
| 253 | + fi |
| 254 | + |
| 255 | +done < ${ARG_INPUTFILE} |
| 256 | + |
| 257 | +echo |
0 commit comments