Signed-off-by: Max <ai-agent@topdoglabs.com>
This commit is contained in:
parent
75aef25ba3
commit
c571130029
278
scripts/sprint-auto-status.sh
Executable file
278
scripts/sprint-auto-status.sh
Executable file
@ -0,0 +1,278 @@
|
||||
#!/bin/bash
|
||||
# Sprint Auto-Status and Rollover Script
|
||||
# Updates sprint statuses based on current date and rolls over incomplete tasks
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/lib/api_client.sh"
|
||||
|
||||
TODAY=$(date +%Y-%m-%d)
|
||||
LOG_FILE="${LOG_FILE:-/tmp/sprint-auto-status.log}"
|
||||
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Get current date in ISO format
|
||||
get_today() {
|
||||
date +%Y-%m-%d
|
||||
}
|
||||
|
||||
# Get all sprints
|
||||
get_all_sprints() {
|
||||
api_call GET "/sprints" | jq -r '.sprints // []'
|
||||
}
|
||||
|
||||
# Determine what status a sprint should have based on date
|
||||
get_sprint_target_status() {
|
||||
local start_date="$1"
|
||||
local end_date="$2"
|
||||
local today="${3:-$(get_today)}"
|
||||
|
||||
if [[ "$today" < "$start_date" ]]; then
|
||||
echo "planning"
|
||||
elif [[ "$today" > "$end_date" ]]; then
|
||||
echo "completed"
|
||||
else
|
||||
echo "active"
|
||||
fi
|
||||
}
|
||||
|
||||
# Update sprint status
|
||||
update_sprint_status() {
|
||||
local sprint_id="$1"
|
||||
local new_status="$2"
|
||||
|
||||
log "Updating sprint $sprint_id to status: $new_status"
|
||||
|
||||
local payload
|
||||
payload=$(jq -n --arg id "$sprint_id" --arg status "$new_status" '{id: $id, status: $status}')
|
||||
|
||||
if api_call PATCH "/sprints" "$payload" > /dev/null 2>&1; then
|
||||
log "✓ Successfully updated sprint $sprint_id to $new_status"
|
||||
return 0
|
||||
else
|
||||
log "✗ Failed to update sprint $sprint_id"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get incomplete tasks for a sprint (status not in done, canceled, closed)
|
||||
get_incomplete_tasks() {
|
||||
local sprint_id="$1"
|
||||
|
||||
api_call GET "/tasks?scope=all" | \
|
||||
jq --arg sid "$sprint_id" '
|
||||
.tasks
|
||||
| map(select(
|
||||
.sprintId == $sid
|
||||
and (.status != "done" and .status != "canceled" and .status != "closed" and .status != "archived")
|
||||
))
|
||||
'
|
||||
}
|
||||
|
||||
# Get current active sprint (the one containing today)
|
||||
get_current_active_sprint() {
|
||||
local today="${1:-$(get_today)}"
|
||||
|
||||
api_call GET "/sprints" | \
|
||||
jq --arg today "$today" '
|
||||
.sprints
|
||||
| map(select(.start_date <= $today and .end_date >= $today))
|
||||
| .[0]
|
||||
'
|
||||
}
|
||||
|
||||
# Move task to new sprint
|
||||
move_task_to_sprint() {
|
||||
local task_id="$1"
|
||||
local new_sprint_id="$2"
|
||||
local old_sprint_name="$3"
|
||||
|
||||
log "Moving task $task_id to sprint $new_sprint_id (from $old_sprint_name)"
|
||||
|
||||
# Get existing task
|
||||
local task
|
||||
task=$(api_call GET "/tasks?taskId=$(urlencode "$task_id")&include=detail" | jq '.tasks[0]')
|
||||
|
||||
if [[ -z "$task" || "$task" == "null" ]]; then
|
||||
log "✗ Task $task_id not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Update sprint ID and add comment
|
||||
local now
|
||||
now=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||
local comment
|
||||
comment="Auto-rolled over from $old_sprint_name on $(get_today)"
|
||||
|
||||
local updated_task
|
||||
updated_task=$(echo "$task" | \
|
||||
jq --arg sid "$new_sprint_id" \
|
||||
--arg comment "$comment" \
|
||||
--arg createdAt "$now" \
|
||||
--arg commentId "$(date +%s)-$RANDOM" '
|
||||
.sprintId = $sid |
|
||||
.comments = (.comments // []) + [{
|
||||
id: $commentId,
|
||||
text: $comment,
|
||||
createdAt: $createdAt,
|
||||
commentAuthorId: "system",
|
||||
replies: []
|
||||
}]
|
||||
')
|
||||
|
||||
if api_call POST "/tasks" "{\"task\": $updated_task}" > /dev/null 2>&1; then
|
||||
log "✓ Successfully moved task $task_id"
|
||||
return 0
|
||||
else
|
||||
log "✗ Failed to move task $task_id"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main function to process sprint updates
|
||||
process_sprint_updates() {
|
||||
log "=== Starting Sprint Auto-Status Update ==="
|
||||
log "Today: $(get_today)"
|
||||
|
||||
# Get all sprints
|
||||
local sprints
|
||||
sprints=$(get_all_sprints)
|
||||
|
||||
if [[ -z "$sprints" || "$sprints" == "[]" ]]; then
|
||||
log "No sprints found"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local updated_count=0
|
||||
local rollover_count=0
|
||||
|
||||
# Process each sprint
|
||||
while IFS= read -r sprint; do
|
||||
[[ -z "$sprint" ]] && continue
|
||||
|
||||
local sprint_id
|
||||
local current_status
|
||||
local start_date
|
||||
local end_date
|
||||
local sprint_name
|
||||
|
||||
sprint_id=$(echo "$sprint" | jq -r '.id // empty')
|
||||
current_status=$(echo "$sprint" | jq -r '.status // empty')
|
||||
start_date=$(echo "$sprint" | jq -r '.start_date // .startDate // empty')
|
||||
end_date=$(echo "$sprint" | jq -r '.end_date // .endDate // empty')
|
||||
sprint_name=$(echo "$sprint" | jq -r '.name // "Unnamed"')
|
||||
|
||||
[[ -z "$sprint_id" ]] && continue
|
||||
|
||||
# Determine target status
|
||||
local target_status
|
||||
target_status=$(get_sprint_target_status "$start_date" "$end_date")
|
||||
|
||||
log "Sprint: $sprint_name (ID: $sprint_id) - Current: $current_status, Target: $target_status"
|
||||
|
||||
# Update if different
|
||||
if [[ "$current_status" != "$target_status" ]]; then
|
||||
if update_sprint_status "$sprint_id" "$target_status"; then
|
||||
((updated_count++))
|
||||
|
||||
# If sprint was just completed, roll over incomplete tasks
|
||||
if [[ "$target_status" == "completed" ]]; then
|
||||
log "Sprint $sprint_name completed - checking for tasks to roll over"
|
||||
|
||||
# Get the new current sprint
|
||||
local current_sprint
|
||||
current_sprint=$(get_current_active_sprint)
|
||||
|
||||
if [[ -n "$current_sprint" && "$current_sprint" != "null" ]]; then
|
||||
local new_sprint_id
|
||||
new_sprint_id=$(echo "$current_sprint" | jq -r '.id')
|
||||
|
||||
# Get incomplete tasks
|
||||
local incomplete_tasks
|
||||
incomplete_tasks=$(get_incomplete_tasks "$sprint_id")
|
||||
|
||||
local task_count
|
||||
task_count=$(echo "$incomplete_tasks" | jq 'length')
|
||||
|
||||
if [[ "$task_count" -gt 0 ]]; then
|
||||
log "Found $task_count incomplete tasks to roll over"
|
||||
|
||||
# Move each task
|
||||
while IFS= read -r task_id; do
|
||||
[[ -z "$task_id" ]] && continue
|
||||
if move_task_to_sprint "$task_id" "$new_sprint_id" "$sprint_name"; then
|
||||
((rollover_count++))
|
||||
fi
|
||||
done < <(echo "$incomplete_tasks" | jq -r '.[].id' 2>/dev/null)
|
||||
else
|
||||
log "No incomplete tasks found"
|
||||
fi
|
||||
else
|
||||
log "Warning: No current active sprint found for rollover"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log "Status is correct, no update needed"
|
||||
fi
|
||||
|
||||
done < <(echo "$sprints" | jq -c '.[]' 2>/dev/null)
|
||||
|
||||
log "=== Sprint Update Complete ==="
|
||||
log "Updated: $updated_count sprints"
|
||||
log "Rolled over: $rollover_count tasks"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Show help
|
||||
show_help() {
|
||||
cat << 'HELP'
|
||||
Sprint Auto-Status and Rollover Script
|
||||
|
||||
USAGE:
|
||||
./sprint-auto-status.sh [command]
|
||||
|
||||
COMMANDS:
|
||||
run Run the auto-status update and rollover process
|
||||
dry-run Show what would happen without making changes
|
||||
cleanup Clean up old log files
|
||||
help Show this help message
|
||||
|
||||
ENVIRONMENT:
|
||||
LOG_FILE Path to log file (default: /tmp/sprint-auto-status.log)
|
||||
API_URL Gantt Board API URL (default: http://localhost:3000/api)
|
||||
|
||||
EXAMPLES:
|
||||
./sprint-auto-status.sh run
|
||||
LOG_FILE=/var/log/sprint-status.log ./sprint-auto-status.sh run
|
||||
HELP
|
||||
}
|
||||
|
||||
# Main execution
|
||||
case "${1:-}" in
|
||||
run)
|
||||
process_sprint_updates
|
||||
;;
|
||||
dry-run)
|
||||
log "=== DRY RUN MODE - No changes will be made ==="
|
||||
# In dry-run mode, we'd print what would happen
|
||||
log "Would check all sprints and update statuses based on $(get_today)"
|
||||
log "Would roll over incomplete tasks from completed sprints"
|
||||
;;
|
||||
cleanup)
|
||||
rm -f /tmp/sprint-auto-status.log
|
||||
log "Cleaned up log files"
|
||||
;;
|
||||
help|--help|-h|"")
|
||||
show_help
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown command: $1"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Loading…
Reference in New Issue
Block a user