Example bash script using Insights to get credits used for a workflow

Hi There!

Recently the Support team created a script for easily getting the total number of credits used on a workflow. This was created since the insights endpoint for workflow credits is scoped per branch, which means you need to do an API call per branch to get this information.

This script will likely need to be modified to be used for your purposes, but should be a good starting point!

A few notes/caveats:

  1. It will only look at branches from the last 100 builds
  2. The credit data that is returned will be for the last 90 days
  3. It does create a file ( branches.txt ) in the current working directory, but deletes it at the end
  4. It requires jq and bc to be installed
  5. Within the Variables section, you will need to enter your API token, organization and project
#!/bin/bash -e

# This script will return the total number of credits used, per branch, for a particular workflow.
# Can be called with "source name_of_file.sh" -- you will be prompted for a workflow name to get data on

### Variables ###
​
# Set to personal API token
CIRCLE_API_TOKEN=
# set to github or bitbucket
VCS=github
# set to organization
ORG=
# set to project
PROJECT=
​
### Commands ###

# Check for Input
read -p 'Workflow Name: ' WORKFLOW
​
if [ -z "$WORKFLOW" ]
  then
    echo "No argument supplied, please enter a workflow name."
    exit 1
fi

BRANCHES=$(curl https://circleci.com/api/v1.1/project/$VCS/$ORG/$PROJECT?circle-token=$CIRCLE_API_TOKEN\&shallow=true\&limit=100 | jq -r '.[] | select (.lifecycle? == "finished") |  .branch' | sort | uniq)
​
echo $BRANCHES | tr " " "\n" > branches.txt
echo
echo "Finding insights .........."
echo

for x in `cat branches.txt` ; do INSIGHTS=$(curl -s https://circleci.com/api/v2/insights/$VCS/$ORG/$PROJECT/workflows/$WORKFLOW?circle-token=$CIRCLE_API_TOKEN\&branch=$x | jq -r '.items[] | .credits_used'); echo; CREDITS=$(echo $INSIGHTS); echo "*** Credits for branch $x ***"; sed 's/ /+/g' <<< $CREDITS | bc; echo; done
# cleanup
​
rm -rf branches.txt
​
#### END ####

The above should result in something like (if the workflow wasn’t run on the branch, the value below that branch will not be present):

Finding insights ..........

*** Credits for branch staging ***
2295

*** Credits for branch param-test ***
1

*** Credits for branch new-workflow-test ***


*** Credits for branch staging-site ***
84

*** Credits for branch test-workflows ***
100
4 Likes

As another example of how you might accomplish this, here is a Ruby script. This one allows you to set the number of builds to check for branches for, in increments of 100.

# install the gems before running: gem install httparty | gem install json | gem install highline
# Run with: ruby filename.rb

require "httparty"
require "json"
require "highline/import"

# Set to your personal API token
API_KEY = ""
# Set to your organization
ORG = ""
# Set to your project
PROJECT = ""
# Set to your VCS (github or bitbucket)
VCS = "github"

# *Danger Zone -- no need to modify*
BRANCH_URL = "https://circleci.com/api/v1.1/project/#{VCS}/#{ORG}/#{PROJECT}?circle-token=#{API_KEY}&shallow=true&limit=100"
INSIGHTS_URL = "https://circleci.com/api/v2/insights/#{VCS}/#{ORG}/#{PROJECT}/workflows"

def error_message(response)
	JSON.parse(response.body)["message"]
end

def loop_number(builds)
	builds.to_i/100
end

def number_of_loops(builds)
	loop_number(builds) == 0 ? 1 : loop_number(builds)
end

how_many_builds = ask "How many builds? (increments of 100):"
workflow = ask "Enter workflow name:"

if workflow.empty?
	puts "No workflow name provided, exiting"
	exit
end 

branches = []

puts "-----------Finding branches-----------"
number_of_loops(how_many_builds).times do |n|
	response = HTTParty.get("#{BRANCH_URL}&offset=#{n*100}")
	if response.code.to_i <= 201
		branches |= JSON.parse(response.body).map { |build| build["branch"] }.compact.uniq
	else 
	   	puts "API call failed: #{response.code}:#{response.message} - #{error_message(response)}"
	   	exit
	end
end

puts "Branches found: #{branches.to_s.gsub /"/, ''}"

credits_arr = []

puts "-----------Finding credits-----------"
branches.each do |branch|
	response = HTTParty.get("#{INSIGHTS_URL}/#{workflow}?circle-token=#{API_KEY}&branch=#{branch}")
	if response.code.to_i <= 201
		puts "Credits used on #{branch}:"
		puts JSON.parse(response.body)["items"].map { |build| build["credits_used"] }.compact.inject(0){ |credits, x| credits + x }
	else
	   	puts "API call failed: #{response.code}:#{response.message} - #{error_message(response)}"
	   	exit
	end
end

Which should provide an output like the following:

$ ruby insights.rb
How many builds? (increments of 100):
500
Enter workflow name:
test_build_and_deploy
-----------Finding branches-----------
Branches found: [main, credit-usage-2, credit-usage, lets-test-filters, aws-orb-test, approval-text]
-----------Finding credits-----------
Credits used on main:
0
Credits used on credit-usage-2:
899
Credits used on credit-usage:
1
Credits used on lets-test-filters:
22
Credits used on aws-orb-test:
0
Credits used on approval-text:
0
1 Like