-
-
Save Draiken/f23a98de94015b794219d9e64ef5c642 to your computer and use it in GitHub Desktop.
Basic Linear CLI using curl and jq
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -euo pipefail | |
: ${LINEAR_API_KEY:?"Please provide your personal API key"} | |
request() { | |
query=${1:?"Please provide a GraphQL query"} | |
variables=${2:-"{}"} | |
data=$(jq -c -n --arg query "$query" --arg variables "$variables" '{"query": $query, "variables": $variables}') | |
curl \ | |
-s \ | |
-X POST \ | |
-H "Content-Type: application/json" \ | |
-H "Authorization: $LINEAR_API_KEY" \ | |
--data "$data" \ | |
https://api.linear.app/graphql | |
} | |
list_states() { | |
teamId=${1:?"Please provide a team ID"} | |
query=$(cat <<EOF | |
query(\$filter: WorkflowStateFilter) { | |
workflowStates(filter: \$filter) { | |
edges { | |
node { | |
id | |
name | |
} | |
} | |
} | |
} | |
EOF | |
) | |
variables=$(jq -c -n --arg id "$teamId" '{ "filter": {"team": { "id": { "eq": $id } } }}') | |
request "$query" "$variables" | jq '.data.workflowStates.edges[].node' | |
} | |
fetch_issue() { | |
id=${1:?"Please provide an issue ID"} | |
query=$(cat <<EOF | |
query(\$id: String!) { | |
issue(id: \$id) { | |
id | |
identifier | |
title | |
description | |
team { | |
id | |
name | |
} | |
} | |
} | |
EOF | |
) | |
variables=$(jq -c -n --arg id "$id" '{"id": $id}') | |
issue=$(request "$query" "$variables" | jq -r '.data.issue') | |
if [ "$issue" = "null" ]; then | |
echo "Issue $id not found" >&2 | |
exit 1 | |
fi | |
echo $issue | |
} | |
show_issue() { | |
id=${1:?"Please provide an issue ID"} | |
fetch_issue "$id" | jq '.' | |
} | |
my_issues() { | |
query=$(cat <<EOF | |
query { | |
viewer { | |
assignedIssues { | |
edges { | |
node { | |
identifier | |
title | |
} | |
} | |
} | |
} | |
} | |
EOF | |
) | |
request "$query" | jq -r '.data.viewer.assignedIssues.edges[].node | "\(.identifier) \t| \(.title)"' | |
} | |
update_issue_state() { | |
id=${1:?"Please provide an issue ID"} | |
state=${2:?"Please provide a state"} | |
issue_details=$(fetch_issue "$id") | |
teamId=$(echo "$issue_details" | jq -r '.team.id') | |
state_id=$(state_named "$teamId" "$state") | |
query=$(cat <<EOF | |
mutation Update(\$input: IssueUpdateInput!, \$id: String!) { | |
issueUpdate(input: \$input, id: \$id) { | |
success | |
issue { | |
identifier | |
title | |
state { | |
name | |
} | |
} | |
} | |
} | |
EOF | |
) | |
variables=$(jq -c -n --arg id "$id" --arg state_id "$state_id" '{"input": {"stateId": $state_id}, "id": $id}') | |
result=$(request "$query" "$variables") | |
echo $result | jq '.' | |
if echo $result| jq -r '.data.issueUpdate.success' | grep -q true; then | |
echo "Issue updated" | |
else | |
echo "Issue update failed" | |
exit 1 | |
fi | |
} | |
state_named() { | |
teamId=${1:?"Please provide a team ID"} | |
name=${2:?"Please provide a state name"} | |
states=$(list_states "$teamId") | |
state=$(echo $states | jq -r "select(.name == \"$name\") | .id") | |
echo "STATE IS $state" >&2 | |
if [ -z "$state" ]; then | |
echo "State \"$name\" not found. Available states are:\n $(echo $states | jq -r '.name')" >&2 | |
exit 1 | |
fi | |
echo $state | |
} | |
usage() { | |
cat <<EOF | |
Usage: linear COMMAND [args] | |
Commands: | |
issue ISSUE_ID - Show issue details | |
my_issues - List issues assigned to you | |
update_state ISSUE_ID STATE - Updates an issue state | |
EOF | |
exit 1 | |
} | |
if [ $# -ge 1 ]; then | |
case "$1" in | |
issue) | |
show_issue "$2" | |
;; | |
update_state) | |
update_issue_state "$2" "$3" | |
;; | |
my_issues) | |
my_issues | |
;; | |
help | *) | |
usage | |
;; | |
esac | |
else | |
usage | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment