Skip to content

Instantly share code, notes, and snippets.

@flipdazed
Last active November 17, 2023 21:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flipdazed/0e2ce987ffa179fe9944ac32db469250 to your computer and use it in GitHub Desktop.
Save flipdazed/0e2ce987ffa179fe9944ac32db469250 to your computer and use it in GitHub Desktop.
Lists all issues that are not assigned to a project
#!/bin/bash
# This script lists all the open issues in specified owner's repository or all repositories if no specific one is given.
# The mandatory parameter is -o (owner) and optional parameters are -r (repository) and -c (cache time).
# If no repository(-r) is mentioned, it fetches issues from all repositories of that owner.
# It also caches results of recently fetched project issues based on cache_time (-c). The default cache_time is 3600 seconds if not passed.
# After fetching all issues, it finds the difference between all_issues and issue_details to get issues not allocated to any project.
# Usage: ./script_name.sh -o [owner] -r [repository] -c [cache_time]
# Example: ./script_name.sh -o Microsoft -r vscode -c 5000
# Be very careful of Case!
owner=""
# Flag to check if owner parameter is passed
owner_flag=false
# Default repository
repo=""
# Check for optional parameters
while getopts r:c:o: flag
do
case "${flag}" in
r) repo=${OPTARG};;
c) cache_time=${OPTARG};;
o) owner=${OPTARG}; owner_flag=true;;
esac
done
# If no owner (-o) is supplied, print error message and exit
if ! $owner_flag
then
echo "Error: Owner (-o) is mandatory!"
exit 1
fi
# ID array to store all issue numbers
if [ -z "$repo" ]
then
# If no repository is specified, search all owner's repositories
all_issues=($(gh search issues -L 500 --state open --owner $owner --json number,repository | jq -c '.[]'))
else
# If a repository is specified, restrict the search to that repository
all_issues=($(gh search issues -R $repo -L 500 --state open --owner $owner --json number,repository | jq -c '.[]'))
fi
# Your existing script to get project-allocated issues starts here
# Array to store issues that are allocated to projects
# echo 'Getting all issues assigned to project...'
project_issue_details=()
cache_dir=".cache"
mkdir -p "$cache_dir" # Make sure the cache directory exists
# Set default cache time if not set
if [ -z "$cache_time" ]
then
cache_time=3600
fi
project_numbers=($(gh project list --owner $owner --format json --closed | jq '.projects[].number'))
for project_number in "${project_numbers[@]}"
do
cache_file="$cache_dir/project_${project_number}_issues"
if [ -f "$cache_file" ]; then
# The cache file exists: check it hasn't expired
file_time=$(stat -f "%m" "$cache_file")
curr_time=$(date +%s)
if [ $(($curr_time - $file_time)) -le $cache_time ]; then
# Cache valid, use cached data
issue_details=($(cat "$cache_file"))
else
# echo "Cache expired. Fetching issues for Project: #${project_number}"
_issue_numbers=($(gh project item-list $project_number --owner $owner --format json | jq -c '.items[].content.number'))
_issue_repo=($(gh project item-list $project_number --owner $owner --format json | jq -c '.items[].content.repository'))
# Get the length of one of the arrays
length=${#_issue_numbers[@]}
# Initialize an empty array
declare -a issue_details
# Combine elements from both arrays
for ((i=0; i<$length; i++)); do
issue_details+=("${_issue_repo[$i]//\"}#${_issue_numbers[$i]}")
done
echo "${issue_details[@]}" > "$cache_file"
fi
else
# No cache exists: fetch data and store in cache
_issue_numbers=($(gh project item-list $project_number --owner $owner --format json | jq -c '.items[].content.number'))
_issue_repo=($(gh project item-list $project_number --owner $owner --format json | jq -c '.items[].content.repository'))
# Get the length of one of the arrays
length=${#_issue_numbers[@]}
# Initialize an empty array
declare -a issue_details
# Combine elements from both arrays
for ((i=0; i<$length; i++)); do
issue_details+=("${_issue_repo[$i]//\"}#${_issue_numbers[$i]}")
done
echo "${issue_details[@]}" > "$cache_file"
fi
# Extend the array
project_issue_details+=("${issue_details[@]}")
done
# Find the difference between all_issues and issue_details to get issues not allocated to any project
echo
echo "Issues in ${repo} not allocated to any project:"
for i in "${all_issues[@]}"; do
# Parse issue number and repository name from the JSON
issue_number=$(echo "$i" | jq '.number')
issue_repo=$(echo "$i" | jq -r '.repository.name')
skip=
for j in "${project_issue_details[@]}"; do
# project_issue_number=$(echo "$j" | jq '.content.number')
# project_issue_repo=$(echo "$j" | jq -r '.content.repository')
[[ $issue_repo != $repo ]] && {
skip=1
break
}
[[ $j == "$owner/$issue_repo#$issue_number" ]] && {
skip=1
break
}
done
[[ -n $skip ]] || {
# Get the issue title and URL using the GitHub API
issue_info=$(gh api repos/$owner/$issue_repo/issues/$issue_number --jq '.title, .html_url')
# Parse the response to get the title and URL
issue_title=$(echo "$issue_info" | awk 'NR==1')
issue_url=$(echo "$issue_info" | awk 'NR==2')
# Print a markdown formatted hyperlink
echo "* \`$owner/$issue_repo#$issue_number\`: [$issue_title]($issue_url)"
}
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment