automation
This commit is contained in:
parent
cbc1881e55
commit
2e1759af8a
@ -12,10 +12,9 @@
|
|||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
I publish a daily stakeholder report to the TSYS Group discourse every day. Up until 11/29 I was performing the publishing step manually.
|
I publish a daily stakeholder report to the TSYS Group discourse every day. Up until 11/29 I was performing the publishing step manually. On 11/29 I automated the pdf creation and publishing to discourse procedure.
|
||||||
On 11/29 I automated the process. I also begin work on automated gathering of data going into the new version of the report.
|
|
||||||
|
|
||||||
These scripts help me maintain a daily report and high fidelity information in the report for my stake holders.
|
I also begin work on automated gathering of data going into the new version of the report that is in development.
|
||||||
|
|
||||||
## Scripts
|
## Scripts
|
||||||
|
|
||||||
|
@ -0,0 +1,97 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Use the Joplin CLI and create a new note for today. Let me pass in the notebook folder path. Use bash functions.
|
||||||
|
|
||||||
|
# Created by chatgpt
|
||||||
|
# https://chatgpt.com/share/6750c7df-6b2c-8005-a91c-1bc5b3875170
|
||||||
|
|
||||||
|
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
|
||||||
|
# Bash3 Boilerplate Setup
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
set -o pipefail
|
||||||
|
IFS=$'\n\t'
|
||||||
|
|
||||||
|
# Constants
|
||||||
|
readonly SCRIPT_NAME=$(basename "$0")
|
||||||
|
readonly SCRIPT_VERSION="1.0"
|
||||||
|
readonly SCRIPT_AUTHOR="Charles N Wyble"
|
||||||
|
readonly SCRIPT_DESC="Create a new Daily Stakeholder Report note in Joplin"
|
||||||
|
|
||||||
|
# Logging and Debugging (from bash3boilerplate)
|
||||||
|
readonly LOG_FILE="/tmp/${SCRIPT_NAME}.log"
|
||||||
|
readonly TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
|
||||||
|
info() { echo "[INFO] [$TIMESTAMP] $*"; }
|
||||||
|
error() { echo "[ERROR] [$TIMESTAMP] $*" >&2; }
|
||||||
|
|
||||||
|
# Default Exit Codes
|
||||||
|
readonly ERR_JOPLIN_NOT_INSTALLED=10
|
||||||
|
readonly ERR_NOTEBOOK_NOT_FOUND=20
|
||||||
|
|
||||||
|
# Function: Usage Instructions
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
$SCRIPT_DESC
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
$SCRIPT_NAME <notebook_folder_path>
|
||||||
|
|
||||||
|
Example:
|
||||||
|
$SCRIPT_NAME "Stakeholder Reports"
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h, --help Display this help message.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check dependencies
|
||||||
|
require_joplin() {
|
||||||
|
if ! command -v joplin &>/dev/null; then
|
||||||
|
error "Joplin CLI is not installed or not in PATH. Please install it and try again."
|
||||||
|
exit $ERR_JOPLIN_NOT_INSTALLED
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if notebook exists in Joplin
|
||||||
|
notebook_exists() {
|
||||||
|
local notebook="$1"
|
||||||
|
if ! joplin use "$notebook" >/dev/null 2>&1; then
|
||||||
|
error "Notebook '$notebook' does not exist. Please create it first."
|
||||||
|
exit $ERR_NOTEBOOK_NOT_FOUND
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create a new note in the specified notebook
|
||||||
|
create_note() {
|
||||||
|
local notebook="$1"
|
||||||
|
local today_date=$(date '+%d-%m-%Y') # Format: YYYY-MM-DD
|
||||||
|
local title="Daily Stakeholder Report - $date"
|
||||||
|
local content="## Daily Stakeholder Report\n\n**Date:** $date\n\n---\n\n### Key Updates\n\n- \n\n### Issues\n\n- \n\n### Next Steps\n\n- \n"
|
||||||
|
|
||||||
|
joplin create note --title "$title" --body "$content" >/dev/null
|
||||||
|
info "Note created successfully in notebook '$notebook'."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main Function
|
||||||
|
main() {
|
||||||
|
local notebook_path="$1"
|
||||||
|
|
||||||
|
# Ensure Joplin CLI is present
|
||||||
|
require_joplin
|
||||||
|
|
||||||
|
# Verify notebook existence
|
||||||
|
notebook_exists "$notebook_path"
|
||||||
|
|
||||||
|
# Create a new note
|
||||||
|
create_note "$notebook_path"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Argument Parsing
|
||||||
|
if [[ $# -lt 1 ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
main "$1"
|
@ -0,0 +1,114 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Written by ChatGPT
|
||||||
|
# https://chatgpt.com/share/6750c7df-6b2c-8005-a91c-1bc5b3875170
|
||||||
|
|
||||||
|
# Prompt:
|
||||||
|
# Pull any issues from Redmine that have a due date of today via API
|
||||||
|
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
|
||||||
|
# Bash3 Boilerplate Setup
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
set -o pipefail
|
||||||
|
IFS=$'\n\t'
|
||||||
|
|
||||||
|
# Constants
|
||||||
|
readonly SCRIPT_NAME=$(basename "$0")
|
||||||
|
readonly SCRIPT_VERSION="1.0"
|
||||||
|
readonly SCRIPT_AUTHOR="Charles N Wyble"
|
||||||
|
readonly SCRIPT_DESC="Pull Redmine issues with a due date of today and output in Markdown"
|
||||||
|
|
||||||
|
# Logging and Debugging
|
||||||
|
readonly LOG_FILE="/tmp/${SCRIPT_NAME}.log"
|
||||||
|
readonly TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
|
||||||
|
info() { echo "[INFO] [$TIMESTAMP] $*" | tee -a "$LOG_FILE"; }
|
||||||
|
error() { echo "[ERROR] [$TIMESTAMP] $*" >&2 | tee -a "$LOG_FILE"; }
|
||||||
|
|
||||||
|
# Default Exit Codes
|
||||||
|
readonly ERR_CURL_NOT_INSTALLED=10
|
||||||
|
readonly ERR_API_FAILURE=20
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
readonly REDMINE_INSTANCE="projects.knownelement.com"
|
||||||
|
readonly REDMINE_API_URL="https://${REDMINE_INSTANCE}"
|
||||||
|
readonly REDMINE_API_KEY="your_api_key_here"
|
||||||
|
readonly DATE=$(date '+%Y-%m-%d')
|
||||||
|
|
||||||
|
# Function: Usage Instructions
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
$SCRIPT_DESC
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
$SCRIPT_NAME <project_id>
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h, --help Display this help message.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
$SCRIPT_NAME 123
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check dependencies
|
||||||
|
require_curl() {
|
||||||
|
if ! command -v curl &>/dev/null; then
|
||||||
|
error "curl is not installed or not in PATH. Please install it and try again."
|
||||||
|
exit $ERR_CURL_NOT_INSTALLED
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fetch issues from Redmine API
|
||||||
|
fetch_issues() {
|
||||||
|
local project_id="$1"
|
||||||
|
local url="${REDMINE_API_URL}/issues.json?key=${REDMINE_API_KEY}&project_id=${project_id}&due_date=${DATE}"
|
||||||
|
|
||||||
|
info "Fetching issues with due date ${DATE} for project ID ${project_id}..."
|
||||||
|
response=$(curl -s -w "%{http_code}" -o /tmp/redmine_response.json "$url")
|
||||||
|
http_code=$(tail -n1 <<<"$response")
|
||||||
|
|
||||||
|
if [[ "$http_code" -ne 200 ]]; then
|
||||||
|
error "Failed to fetch issues from Redmine API. HTTP Code: $http_code"
|
||||||
|
exit $ERR_API_FAILURE
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "Issues fetched successfully. Parsing and converting to Markdown..."
|
||||||
|
generate_markdown /tmp/redmine_response.json
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate Markdown output from JSON response
|
||||||
|
generate_markdown() {
|
||||||
|
local json_file="$1"
|
||||||
|
local markdown_output="/tmp/redmine_issues.md"
|
||||||
|
|
||||||
|
echo "# Redmine Issues for ${DATE}" > "$markdown_output"
|
||||||
|
echo "" >> "$markdown_output"
|
||||||
|
|
||||||
|
jq -r --arg base_url "$REDMINE_API_URL" '.issues[] | "## [\(.subject)](\($base_url)/issues/\(.id))\n- **ID**: \(.id)\n- **Status**: \(.status.name)\n- **Due Date**: \(.due_date)\n\n---"' \
|
||||||
|
"$json_file" >> "$markdown_output"
|
||||||
|
|
||||||
|
info "Markdown output written to $markdown_output"
|
||||||
|
cat "$markdown_output"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main Function
|
||||||
|
main() {
|
||||||
|
local project_id="$1"
|
||||||
|
|
||||||
|
# Ensure curl is installed
|
||||||
|
require_curl
|
||||||
|
|
||||||
|
# Fetch issues for the project
|
||||||
|
fetch_issues "$project_id"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Argument Parsing
|
||||||
|
if [[ $# -lt 1 ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
main "$1"
|
||||||
|
|
BIN
dsr-publish/.daily-stakeholder-report.yml.swp
Normal file
BIN
dsr-publish/.daily-stakeholder-report.yml.swp
Normal file
Binary file not shown.
@ -1,8 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
TODAY_DATE=$(date +%m-%d-%Y)
|
TODAY_DATE=$(date +%m-%d-%Y)
|
||||||
INPUT_FILE="./DSR-$TODAY_DATE.md"
|
INPUT_FILE="../dsrtemp/@DailyStakeholderReports/Today/DSR-$TODAY_DATE.md"
|
||||||
OUTPUT_FILE="./DSR-$TODAY_DATE.pdf"
|
OUTPUT_FILE="../dsrtemp/DSR-$TODAY_DATE.pdf"
|
||||||
METADATA_FILE="daily-stakeholder-report.yml"
|
METADATA_FILE="daily-stakeholder-report.yml"
|
||||||
TEMPLATE="eisvogel"
|
TEMPLATE="eisvogel"
|
||||||
|
|
||||||
@ -12,4 +12,4 @@ $INPUT_FILE \
|
|||||||
--metadata-file=$METADATA_FILE \
|
--metadata-file=$METADATA_FILE \
|
||||||
--from markdown \
|
--from markdown \
|
||||||
--to=pdf \
|
--to=pdf \
|
||||||
--output $OUTPUT_FILE
|
--output $OUTPUT_FILE
|
||||||
|
10
dsr-publish/daily-stakeholder-report.yml
Normal file
10
dsr-publish/daily-stakeholder-report.yml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
title: Daily Stakeholder Report - \date
|
||||||
|
titlepage: true
|
||||||
|
header-left: "\\hspace{1cm}"
|
||||||
|
header-center: "\\leftmark"
|
||||||
|
header-right: "Page \\thepage"
|
||||||
|
footer-left: "Charles N Wyble"
|
||||||
|
footer-center: "Tenacity. Velocity. Focus."
|
||||||
|
footer-right: "[Source code](https://git.knownelement.com/reachableceo/DailyStakeholderReport-Pipeline/src/branch/main/dsr-publish/create-dsr-pdf.sh)"
|
||||||
|
page-background: "D:/tsys/@ReachableCEO/ExternalVendorCode/pandoc-latex-template/examples/page-background/backgrounds/background5.pdf"
|
||||||
|
titlepage-logo: "D:/tsys/@ReachableCEO/ReachableCEO.png"
|
@ -39,6 +39,9 @@ export DISCOURSE_APIKEY="$(bw get password APIKEY-discourse)"
|
|||||||
post_dsr()
|
post_dsr()
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
TODAY_DATE=$(date +%m-%d-%Y)
|
||||||
|
|
||||||
echo "Posting DSR..."
|
echo "Posting DSR..."
|
||||||
|
|
||||||
DISCOURSE_URL="https://community.turnsys.com" # e.g., https://forum.example.com
|
DISCOURSE_URL="https://community.turnsys.com" # e.g., https://forum.example.com
|
||||||
@ -55,7 +58,7 @@ TITLE="Daily Stakeholder Report - $TODAY_DATE"
|
|||||||
CONTENT="Please use the link below to download today's stakeholder report."
|
CONTENT="Please use the link below to download today's stakeholder report."
|
||||||
|
|
||||||
# The file to upload (from the second argument or auto-generated based on date)
|
# The file to upload (from the second argument or auto-generated based on date)
|
||||||
FILE_PATH="./DSR-$TODAY_DATE.pdf"
|
FILE_PATH="../dsrtemp/DSR-$TODAY_DATE.pdf"
|
||||||
|
|
||||||
# Check if the file exists
|
# Check if the file exists
|
||||||
if [ ! -f "$FILE_PATH" ]; then
|
if [ ! -f "$FILE_PATH" ]; then
|
||||||
@ -125,4 +128,4 @@ secrets_manager
|
|||||||
# - upload PDF to discourse
|
# - upload PDF to discourse
|
||||||
# - attach uploaded PDF to the topic
|
# - attach uploaded PDF to the topic
|
||||||
|
|
||||||
post_dsr
|
post_dsr
|
||||||
|
Loading…
x
Reference in New Issue
Block a user