├── README.md ├── gh-quickcs └── images └── quickcs-example.png /README.md: -------------------------------------------------------------------------------- 1 | # gh-quickcs 2 | 3 | A GitHub CLI extension that lets you quickly create a new codespace for a preconfigured repository. 4 | 5 | ## 📦 Installation 6 | 7 | 1. If you haven't already, install the `gh` CLI - see the [installation](https://github.com/cli/cli#installation) 8 | 9 | _Installation requires a minimum version (2.0.0) of the the GitHub CLI that supports extensions._ 10 | 11 | 1. Use the GitHub CLI to install the extension: 12 | 13 | ``` 14 | gh ext install hubwriter/gh-quickcs 15 | 16 | Cloning into '/Users/yourname/.local/share/gh/extensions/gh-quickcs'... 17 | remote: Enumerating objects: 35, done. 18 | remote: Counting objects: 100% (35/35), done. 19 | remote: Compressing objects: 100% (30/30), done. 20 | remote: Total 35 (delta 6), reused 24 (delta 3), pack-reused 0 21 | Receiving objects: 100% (35/35), 9.65 KiB | 4.83 MiB/s, done. 22 | Resolving deltas: 100% (6/6), done. 23 | ✓ Installed extension hubwriter/gh-quickcs 24 | ``` 25 | 26 | ## ⚡️ Usage 27 | 28 | 1. Run 29 | 30 | ```sh 31 | gh quickcs 32 | ``` 33 | 34 | 1. _On first run only:_ The first time you use the extension it will ask you to input configuration options. This is a one-time operation. The values you enter are stored in `~/.gh-quickcs.cfg`. You can edit this file if you need to change the values, but the rationale of this script is that you want to create the same kind of codespace for the same repository, so you won't need to change these values once you've set them. 35 | 1. Enter a display name for the codespace you want to create. Don't use quote marks around the name. The name can include spaces and hyphens. 36 | 1. _Optionally (depending on whether you set true or false for the REQUEST_BRANCH config setting):_ Enter the name of a new branch you want to create, or press Enter to use the default branch. 37 | 38 | ### Example 39 | 40 | image 41 | 42 | ## ⭐ If you like it, star it! 43 | 44 | If you like this CLI extension, please star the repo by clicking **☆ Star** top right of this page. 45 | 46 | This helps raise the profile of this extension. Thanks. 47 | -------------------------------------------------------------------------------- /gh-quickcs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # gh-quickcs = quick codespace 4 | # This extension for GitHub CLI creates a codespace for a preconfigured repo. 5 | # Use: gh quickcs 6 | # Created by Alistair Christie (@hubwriter) 2023-01-26 7 | 8 | set -e 9 | CONFIG_FILE=~/.gh-quickcs.cfg 10 | 11 | # Create a config file if it doesn't exist. 12 | if [ ! -f "$CONFIG_FILE" ]; then 13 | echo "The configuration file $CONFIG_FILE does not exist. Let's create it." 14 | echo "This is a one-time setup task."; echo 15 | read -p "Enter the name of the repository you want to use for your codespace (e.g. repo-owner/repo-name): " REPO 16 | eval "gh api -H \"Accept: application/vnd.github+json\" /repos/$REPO" >/dev/null 2>&1 || { echo "The repository $REPO does not exist. Please try again."; exit 1; } 17 | read -p "Enter the path to a custom devcontainer.json file (or press Enter for the default configuration): " DEVCONTAINER 18 | echo "The available machine types for this repository are are:" 19 | machine_array=( $(eval gh api --jq ".machines[].name" repos/$REPO/codespaces/machines) ) 20 | printf -v machine_list '%s, ' "${machine_array[@]}" # Join the array elements with commas 21 | echo "${machine_list%,?}" # Remove the final comma from the list 22 | until [[ $found_in_array ]]; do 23 | read -p "Enter the machine type for your codespace (or press Enter to use basicLinux32gb): " MACHINE 24 | if [ -z "${MACHINE}" ]; then MACHINE="basicLinux32gb"; fi 25 | for item in "${machine_array[@]}"; do 26 | [[ $MACHINE == "$item" ]] && found_in_array=true 27 | done 28 | if [ ! $found_in_array ]; then echo "$MACHINE is not a valid machine type for this repository."; fi 29 | done 30 | until [[ $TIMEOUT == @([1-9]*([0-9])) && $TIMEOUT -gt 4 && $TIMEOUT -le 241 ]]; do 31 | if [ ! -z ${TIMEOUT+x} ]; then echo "Please enter a number in the range 5-240."; fi 32 | read -p "Enter the idle timeout for your codespace (in whole minutes between 5 and 240): " TIMEOUT 33 | done 34 | until [[ $RETENTION == @(0|[1-9]*([0-9])) && $RETENTION -le 720 ]]; do 35 | if [ ! -z ${RETENTION+x} ]; then echo "Please enter a number in the range 0-720."; fi 36 | read -p "Enter the retention period for your codespace (in whole hours between 0 and 720): " RETENTION 37 | done 38 | read -p "Do you want to create a new branch when you create a codespace? (Y/n): " REQUEST_BRANCH 39 | if [ "$REQUEST_BRANCH" == "n" ]; then 40 | REQUEST_BRANCH="false" 41 | else 42 | REQUEST_BRANCH="true" 43 | fi 44 | read -p "Do you want to open the codespace in your browser? (Y/n): " OPEN_IN_BROWSER 45 | if [ "$OPEN_IN_BROWSER" == "n" ]; then 46 | OPEN_IN_BROWSER="false" 47 | else 48 | OPEN_IN_BROWSER="true" 49 | fi 50 | printf "# Configuration file for the quickcs (quick codespace) GitHub CLI extension.\n\n" > $CONFIG_FILE 51 | printf "REPO=\"$REPO\" # e.g. hubwriter/quickcs\n" >> $CONFIG_FILE 52 | printf "DEVCONTAINER=\"$DEVCONTAINER\" # e.g. .devcontainer/custom-config/devcontainer.json.\n" >> $CONFIG_FILE 53 | printf " # Set an empty string, or delete the DEVCONTAINER entry, to use the default configuration.\n" >> $CONFIG_FILE 54 | printf "MACHINE=\"$MACHINE\" # a valid machine type string\n" >> $CONFIG_FILE 55 | printf "TIMEOUT=\"${TIMEOUT}m\" # minutes in the range 5-240\n" >> $CONFIG_FILE 56 | printf "RETENTION=\"${RETENTION}h\" # hours in the range 0-720\n" >> $CONFIG_FILE 57 | printf "REQUEST_BRANCH=$REQUEST_BRANCH # Set to true to request a branch name, or false to use the default branch.\n" >> $CONFIG_FILE 58 | printf "OPEN_IN_BROWSER=$OPEN_IN_BROWSER # Set to true to open the codespace in a browser, or false to open in VS Code.\n" >> $CONFIG_FILE 59 | 60 | echo "The configuration file $CONFIG_FILE has been created. You can edit it to change the default settings." 61 | fi 62 | 63 | # Load the config file. 64 | source ~/.gh-quickcs.cfg 65 | 66 | echo -e "\nCreate a new codespace for the $REPO repo." 67 | read -p "Enter a codespace display name: " DISPLAYNAME 68 | 69 | if [ "$REQUEST_BRANCH" = true ]; then 70 | read -p "Enter a name for a new branch (or press Enter to use the default branch): " BRANCH 71 | fi 72 | 73 | CREATE_COMMAND="gh cs create -R $REPO -d '$DISPLAYNAME' --idle-timeout $TIMEOUT -m $MACHINE --retention-period $RETENTION" 74 | if [ ! -z "$DEVCONTAINER" ]; then # If DEVCONTAINER is set and not empty 75 | CREATE_COMMAND="$CREATE_COMMAND --devcontainer-path $DEVCONTAINER" 76 | fi 77 | 78 | echo 79 | if [[ "$BRANCH" =~ ( |\') ]]; then 80 | echo "Branch names cannot contain spaces or single quotes." 81 | exit 1 82 | elif [ ! -z "$BRANCH" ]; then # If BRANCH is set and not empty 83 | CREATE_COMMAND="$CREATE_COMMAND -b $BRANCH" 84 | # Get the SHA for the default branch: 85 | SHA=$(eval "gh api repos/$REPO/git/ref/heads/main --jq .object.sha") 86 | # Create a remote branch 87 | API_CALL="gh api --method POST -H \"Accept: application/vnd.github+json\" /repos/$REPO/git/refs -f ref=\"refs/heads/$BRANCH\" -f sha=\"$SHA\"" 88 | echo $API_CALL 89 | eval $API_CALL > /dev/null 90 | fi 91 | 92 | echo $CREATE_COMMAND; echo 93 | 94 | # Create the codespace in a subshell to allow interactive input 95 | bash -c "$CREATE_COMMAND" 96 | 97 | # Get the name of the most recently created codespace 98 | NEW_CODESPACE=$(gh cs list | tail -1 | awk '{print $1}') 99 | 100 | if [ "$OPEN_IN_BROWSER" = true ]; then 101 | OPEN_COMMAND="gh codespace code -w -c '$NEW_CODESPACE'" 102 | else 103 | OPEN_COMMAND="gh codespace code -c '$NEW_CODESPACE'" 104 | fi 105 | 106 | if [ ! -z "$NEW_CODESPACE" ]; then 107 | echo "Codespace created. Internal name: $NEW_CODESPACE. Display name: $DISPLAYNAME."; echo 108 | eval $OPEN_COMMAND 109 | fi 110 | -------------------------------------------------------------------------------- /images/quickcs-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hubwriter/gh-quickcs/1abf10b737f5e15534fba81153b6d971066cc9ea/images/quickcs-example.png --------------------------------------------------------------------------------