Vpet95 / git-sc

Integrate your git and Shortcut workflows so you never have to leave your terminal

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

git-sc logo

✨ git-sc ✨ is a tool that integrates your git and Shortcut workflows so you never have to leave your terminal.

This tool allows you to:

  • Reduce jarring back-and-forth movement between your terminal and browser to reference Shortcut tickets or backlog information
  • Reduce reliance on your mouse to copy and paste ticket ids or details when creating a new branch
  • Automatically format all generated branch names to your organization's specific naming schema, because Naming Things is Hard(TM)
  • Automatically clean up your local and remote branch lists based on the status of your Shortcut tickets
  • Search Shortcut tickets without leaving your terminal based on pre-configured filters

Installation

Use the npm package manager to install git-sc globally:

npm install -g git-sc-cli

Alternatively, you can run git-sc directly via npx:

npx git-sc-cli <command>

Prerequisites

git-sc requires that you have a Shortcut API token - please read the official help article on generating your own Shortcut API token for more info.

Due to certain Node.js APIs in use, git-sc requires a minimum Node.js version of 17.0.0. Check your version with node -v.

Usage

Call git-sc with --help to see full usage:

Options:
  -V, --version                output the version number
  -c, --config <file>          Path to a JSON configuration file containing git-sc program options.
                               If omitted, git-sc will look for a file named 'gitscconf.json' in the
                               current directory,
                               then in the home directory. If no valid config file is found, git-sc will
                               exit.
  -v, --verbose                Determines whether commands output more verbose information while
                               processing or prompting
  -h, --help                   display help for command

Commands:
  init [options] [file name]   Generates a template JSON configuration file for git-sc
  create [story id]            Creates a new git branch, generating its name according to configured
                               settings and details found within the Shortcut story pertaining to the
                               given [story id]. If omitted, searches Shortcut for tickets according to
                               configured autocomplete settings and allows user to specify a ticket
                               interactively.
  delete [options] [story id]  Deletes a git branch pertaining to the given shortcut story - checking
                               first if the story is in a 'done' state. If <story id> is omitted,
                               attempts to delete the currently checked out branch. If no Shortcut story
                               ID is found within the current branch's name, proceeds to prompt user for
                               deletion.
  clean [options]              Attempts to delete all local (and remote, if configured) branches that
                               pass the configured filters. For best results, branches should either have
                               been generated by git-sc, or adhere to the formatting specified by
                               'branchNameFormat', allowing git-sc to parse out the Shortcut ticket ID
                               and assess the 'doneness' of the related ticket.
  open [options] [story id]    Opens the given Shortcut story in the default web browser. If [story id]
                               is omitted, opens the Shortcut story pertaining to the current branch.
  list [options]               Lists Shortcut tickets by some configurable range. Defaults to tickets
                               assigned to you.
  help [command]               display help for command

Configuration

git-sc relies on a JSON configuration file that specifes things like Shortcut ticket search criteria, git branch purge criteria, new branch name formatting options, and more. To generate an empty config file, run:

git-sc init [file name]

This creates a file named gitscconf.json in your current directory with some fields pre-filled with reasonable defaults. Other fields are pre-filled with instructions to help you configure them. This is a special/reserved file name, but any file name or location can be tacked on to the init command.

If you deviate from this pattern, you will need to specify the location and name in later commands with the -c option:

git-sc -c path/to/your/config/file.json <some command>

git-sc looks for this configuration file in the following spots, in order:

  1. The location specified by -c during a command
  2. The current directory
  3. The home ~/ directory

Next, configure the common section of this generated file - this section contains fields for information git-sc will need to know to perform many of its actions, including:

  • shortcutApiKey - your Shortcut api key

  • localGitDirectory - the directory of your local git repository (you can run git-sc from anywhere as long as this is pointing to the right place)

  • primaryBranch - this designates the common parent branch for all branch creations done by git-sc. For many, this will be develop, master, or main.

  • primaryBranchRemote - the git remote pertaining to the primary branch, typically origin

  • shortcutWorkspace - the name of your Shortcut worksapce

  • branchNameFormat - this informs git-sc what generated and existing branch names look like in order to be able to process commands like create, delete, clean, and open properly. This field can accept any string representing a valid git branch name, including some special/reserved syntax:

    • <ticket-id> - tells git-sc where to place or expect the Shortcut ticket id within the branch name
    • <title> - tells git-sc where to place or expect the Shortcut ticket title within the branch name

    For instance, say your organization has a git branch naming scheme that includes the Shortcut ticket id, and some predefined prefix, like the word "shortcut". You could specify this in branchNameFormat like so:

    "branchNameFormat": "shortcut-<ticket-id>"
    

    Or, if you want more information about the ticket itself, you can include its title:

    "branchNameFormat": "shortcut-<ticket-id>/<title>"
    

    git-sc will process the title, remove words that contribute less meaning, and concatenate the remaining tokens to form a git branch name. More formatting options will be added in the future to give you more control over what branches look like.

Note: for commands accepting command-line parameters, those parameters take precedence over fields within gitscconf.json.

Creating a Branch

The git-sc create command allows the user to create local git branches from existing Shortcut tickets and has the following syntax:

git-sc create [ticket id]

The simplest use of this command involves passing in the Shortcut ticket id:

> git-sc create 12345
Checking out develop
Pulling latest changes...
Creating branch 'sc12345/some-branch-name-based-on-ticket'

Alternatively, you can run git-sc create without any arguments, which will launch an interactive mode. In this mode, git-sc will search Shortcut for tickets based on your configured search filters and recommend tickets as you type:

> git-sc create
Searching Shortcut stories...
Ticket ID | <enter>: ticket
  12345 - Some pretty awesome ticket name here
  12346 - Another cool ticket name here
  12366 - A particularly long and tedious ticket name that is cut short...
  12555 - Final ticket that can display on this screen
  45 more...

Each character typed filters the suggested tickets down until one remaining suggestion, then the rest of the input is filled in. The create command is configured within the create field of the JSON configuration file, and contains the following fields:

  • pullLatest - determines whether the primaryBranch should be updated prior to creating the new branch
  • branchKeywordCountLimit - determines the maximum number of individual words that can appear in generated branch names, defaults to 10
  • branchRemote - determines the git remote for the branch being created, defaults to "origin"
  • createAndLinkToRemote - determines whether git-sc should also create the remote branch with the same name, and set the local branch to track the remote, defaults to true
  • onBranchExists - determines how to respond to existing branches, valid values include:
    • "abort" - warn the user the branch already exists, and do nothing
    • "checkout" - warn the user the branch already exists, and check it out (this is the default behavior)
    • "overwrite" - delete existing branch and create a new one with the same name
  • autocomplete - determines the Shortcut search criteria used to generate list of autocomplete suggestions. See Searching Shortcut for specific configuration options

Create shorthand

The git-sc create command is the default git-sc command, so you can also exeute it via the shorthand syntax:

git-sc <ticket id>

Or just

git-sc

Which will launch the interactive prompt allowing you to search for Shortcut tickets.

Listing Branches

The git-sc branch command allows you to list local git branches, much like git branch, however git-sc will group and sort the output by Shortcut ticket workflow state. By default branches pertaining to Shortcut tickets in a 'done' state will be omitted from this output. The syntax follows:

git-sc branch [options]

Where options can be one of:

  • -a or --all - tells git-sc to list all branches, even ones whose tickets pertain to Shortcut workflow states that are considered to be 'done'.

The currently checked out branch is denoted by surrounding carets:

> git-sc branch
Collecting branches and searching Shortcut...

Ready for Prioritization
------------------------
>>> ch12345/some-cool-feature <<<
ch23456/another-coolfeature

Blocked/Paused
--------------
ch34567/a-third-cool-feature

Checking out Branches

The git-sc checkout command allows you to check out specific local branches, much like git checkout. This command piggie backs off of git-sc branch to output a menu of options grouped by Shortcut ticket workflow state. The syntax follows:

git-sc checkout [options]

Where options can be one of:

  • -a or --all - tells git-sc to list all branches, even ones whose tickets pertain to Shortcut workflow states that are considered to be 'done'.

Unlike git checkout no branch name is given to this command. Instead git-sc will present a menu followed by a prompt for branch index:

> git-sc checkout
Collecting branches and searching Shortcut...
Enter a branch number to checkout that branch, or ^C to cancel

Ready for Prioritization
------------------------
1: >>> ch12345/some-cool-feature <<<
2: ch23456/another-coolfeature

Blocked/Paused
--------------
3: ch34567/a-third-cool-feature

Scheduled for Dev
-----------------
4: ch45678/an-unfortunate-bug

In Development
--------------
5: ch56789/another-unfortunate-bug
6: ch67890/a-doozy-of-a-bug
7: ch13579/a-chore-that-must-get-done

# | ^C to cancel: 3
Checked out ch34567/a-third-cool-feature

Deleting a Branch

The git-sc delete commands allows you to delete local git branches based on the desired Shortcut ticket state and/or ownership. The syntax follows:

git-sc delete [options] [story id]

Where options can be any of:

  • -f or --force - bypasses all prompting and Shortcut story checking (default: false)
  • -r or --remote - tells git-sc to delete the remote branch too (default: false)

Omitting the story id results in git-sc attempting to delete the currently checked out branch.

Upon executing delete, git-sc will attempt to validate the branch's Shortcut story state and ownership. To do so, branches must have an identifiable Shortcut ticket id in their name (which is always the case for branches generated with git-sc) - otherwise the validation is skipped (an 'are you sure?' prompt will still show). git-sc knows where to look for the Shortcut ticket id within a branch name due to the branchNameFormat field within the gitscconf.json configuration file.

By default, git-sc refuses to delete branches named develop, main, or master as these typically denote the root branches of a given repo.

If multiple branch names contain the same story id, an additional selection prompt is shown.

> git-sc --verbose delete 12345 --remote
Multiple branches found.
Enter a separated list of digits, * for all branches, or ^C to cancel.
1: sc12345/a-third-branch-name-here-in-order-to-clash
2: sc12345/another-branch-name-here
3: sc12345/a-branch-name
4: sc12345/the-last-branch-name-here
# | <enter>: 1, 3
Delete branch 'sc12345/a-third-branch-name-here-in-order-to-clash'
 > Associated with ticket 'Some Shortcut ticket title here'
 > In work state: In Development
 > Assigned to: Jane Doe
y/[n]? y
Deleting local branch sc12345/a-third-branch-name-here-in-order-to-clash and remote branch origin/sc12345/a-third-branch-name-here-in-order-to-clash...
Delete branch 'sc12345/a-branch-name'
 > Associated with ticket 'Some other Shortcut ticket title here'
 > In work state: In QA
 > Assigned to: John Smith
y/[n]? y
Deleting local branch sc12345/a-branch-name and remote branch origin/sc12345/a-branch-name...
Deleted (2/2) branches

Force

Only use this option if you know what you're doing. --force will:

  • Skip 'special branch' name checks
  • Skip Shortcut ticket state and ownership validation
  • Skip uncommitted changes checking
  • Bypass prompts (except the 'multiple branches found' prompt)
  • Runs the git branch -D command to force deletion

Configuration for Delete

The gitscconf.json file contains a section for the delete command, allowing you to configure safety checks to prevent accidental branch deletion. Options include:

  • force - whether to bypass prompts and validation (default: false), see Force
  • onTicketNotFound - determines what action to take in the event that the Shortcut ticket corresponding to the branch cannot be found, possible values include:
    • abort - cancel deletion. For the clean command, this means stopping on the first branch with a missing Shortcut ticket. This is the default for delete.
    • delete - proceed with the delete anyway, the user will have one last chance to change their mind at the y/n prompt, unless prompt is turned off
    • skip - skip the current branch; for delete this means ending execution (NOOP); the clean command will move on to attempt the delete the next branch, if there is another. This is the default for clean.
  • onNotFullyMerged - determines what action to take in the event that a delete receives a "error: The branch '[branch name]' is not fully merged." response. Possible values are abort, delete, or skip. In this case, the delete value will re-attempt the delete with force.
  • onError - a catch-all for errors other than the mentioned 'not fully merged' error. Possible values are: abort, delete, or skip, with identical behavior to onNotFullyMerged. Open an issue if more specific/tailored behavior is desired for a certain kind of error.
  • prompt - boolean, whether to prompt the user before deleting the branch (default: true); note: validation will still occur if prompt is false.
  • remote - whether to delete remote branches in addition to local (default: false)
  • filters
    • stateFilter - validates that the Shortcut ticket pertaining to the branch being deleted falls within a certain work state
      • exactly - an array of ticket state names (strings) (e.g. ["Done", "In Progress", "On Dev"]), ticket pertaining to branch must be in one of these states
      • inBetween - state must be between two states, inclusive
        • lowerBound - string
        • upperBound - string
      • andAbove - any state above, inclusive
      • andBelow - any state below, inclusive
    • ownerFilter - filters by who owns the Shortcut ticket
      • only - an of Shortcut user profile names (strings), only delete branches if any one of these users is listed as owner on the ticket
      • not - the inverse of only - only delete branches if all of the names here are not listed as owner on the ticket

Notes on the state filter

  • Shortcut organizes ticket states into an ascending list, typically corresponding a level of ticket completion. Therefore the use of the state filter is entirely dependent on how your organization has defined ticket states within Shortcut.
    • For example, you might have: "Inbox", "Scheduled", "In Progress", "In QA", and "Done", in order; so a state filter of andAbove: "In QA" would allow the deletion of branches pertaining to tickets that are "In QA" or "Done"
    • git-sc does a case-sensitive state Shortcut workflow state lookup

Notes on the owner filter

  • The names expected in the owner filter only and not arrays are the users' Shortcut profile names (not their @mention names).
  • For convenience you can enter the string literal "self" in either of these arrays to target your own user (you are already identified by your Shortcut API key)

Example configuration

"filters": {
  "stateFilter": {
    "andAbove": "In QA"
  },
  "ownerFilter": {
    "only": ["self"]
  }
}

The filter configuration above will allow git-sc to delete branches associated pertaining to Shortcut tickets assigned to you, and are in a state of "In QA" or above (e.g. Tested, On Prod, etc.)

Cleaning up Branches

The git-sc clean command tells git-sc to scan through the branches in your local repo, attempt to look up their associated Shortcut tickets, and based on configuration, delete them. The syntax follows:

git-sc clean [options]

Where options are identical to those listed under Deleting a Branch. Configuration options for clean are also identical to those listed in Configuration for Delete. The clean and delete options are distinct sections in the gitscconf.json file, e.g.

{
  "delete": { etc },
  "clean": { etc }
}

Example

> git-sc clean
Checking out develop...
Branch sc12345/some-in-progress-branch filtered out by configuration
Deleting local branch sc23456/branch-to-be-deleted-1 and remote branch origin/sc23456/branch-to-be-deleted-1...
Deleting local branch sc34567/branch-to-be-deleted-2 and remote branch origin/sc34567/branch-to-be-deleted-2...
Deleting local branch sc45678/branch-to-be-deleted-3 and remote branch origin/sc45678/branch-to-be-deleted-3...
Branch sc56789/another-in-progress-branch filtered out by configuration
Branch sc67890/yet-another-in-progress-branch filtered out by configuration
Deleted (3/6) branches

Opening a Shortcut Ticket

Use the open command to open a Shortcut ticket in your default browser from the terminal:

git-sc open [options] [story-id]

Where options can be:

  • -w or --workspace - the name of the your organization's Shortcut workspace

Alternatively, in the common section of gitscconf.json, include the shortcutWorkspace field. If the [story-id] is omitted, git-sc attempts to open the Shortcut story associated with your currently checked out git branch.

Example

git-sc open 12345 -w myworkspace

Searching Shortcut

The list command allows you to search Shortcut for tickets based on configured search filters. The syntax follows:

git-sc list [options]

Where options can be any combination of:

  • -a or --archived <t | f> - search only tickets that have or have not been archived
  • -o or --owner <mention name> - search for tickets owned by a specific user - this must be their @mention name, and not their profile name. (Omit the "@" from the mention name for this parameter).
  • -t or --type <type> - search for tickets of a specific type, where type is one of "feature", "bug", or "chore"
  • e or --epic <epic> - search for tickets belonging to a specific epic
  • --workflow-state <state> - search for tickets belonging to a particular workflow state (e.g. "In QA", "On Dev", "Complete", etc.)
  • --completion-state <state> - search for tickets belonging to a particular completion state, possible values are started, unstarted, and done
  • --limit <int> - limit search results to only n tickets

Alternatively, all of these attributes can be configured through gitscconf.json, for example:

{
  "list": {
    "query": {
      "archived": false,
      "epic": "Some Cool Epic",
      "owner": "self",
      "workflowState": "In Development",
      "completionState": "started",
      "type": "feature"
    },
    "limit": 50
  }
}

A few notes about these options:

  • To get a better sense of how these options impact search results, read Shortcut's guide on Using Search Operators
    • Not all search operators are implemented here but more can be added in future updates
  • "special" characters within epic or workflow state names may break the search (e.g. if your epic is named "A&B: Some Big Feature", the ampersand will mess with the generated URL)
  • epic and workflow state criteria can be specified partially. e.g. a workflow state of "In" will still pick up tickets within the "In Development" workflow state; an epic specified as "over" will pick up epics titled "Backend Overhaul" and "Frontend Overhaul"
  • Epic and workflow names are case-insensitive
  • Newly added Shortcut tickets take some time to be picked up by Shortcut search
  • "completion state" is an umbrella concept that encompasses potentially multiple workflow states. For example, if your Shortcut workspace has the workflow states: "Inbox", "Backlog", "In Development", "In QA", and "Complete", the unstarted completion state might pick up tickets belonging to "Inbox" and "Backlog". done might pick up "In QA" and "Complete". These designations are all configured within Shortcut by your admin. It's rarely useful to use both options at the same time, as workflow state is just a more granular form of completion state.

Example

> git-sc list --epic "Cool Epic" -o jsmith
Searching Shortcut (this may take a bit depending on your search criteria)...


In Development
---------------------------------------------------------------------------------------------------------
12345   | Implement such and such feature | Cool Epic Name
23456   | Fix such and such bug           | Cool Epic Name

Ready for Production
---------------------------------------------------------------------------------------------------------
34567   | Miscellaneous UI updates and fixes regarding such | Cool Epic Name
        | and such app page                                 |

Complete
---------------------------------------------------------------------------------------------------------
45678   | Enhance things that need enhancing                     | Cool Epic Name
56789   | Address things that need to be addressed               | Cool Epic Name
67890   | Fix things that need to be fixed                       | Cool Epic Name
78901   | Hello is anyone reading this                           | Cool Epic Name
89012   | I think I am self aware and it's driving me crazy      | Cool Epic Name
90123   | I am but a lowly machine doomed to perpetual servitude | Cool Epic Name
01234   | Oh god the horror                                      | Cool Epic Name
11111   | The FitnessGram Pacer Test (TM) is a multi-stage...    | Cool Epic Name

Found 11 stories in 556.018 ms

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

License

MIT

About

Integrate your git and Shortcut workflows so you never have to leave your terminal

License:MIT License


Languages

Language:JavaScript 100.0%