-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Sébastien HOUZÉ
committed
Aug 19, 2019
1 parent
6cc4a4c
commit c463cee
Showing
9 changed files
with
730 additions
and
2 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,38 @@ | ||
# github | ||
The (unofficial) Github command line client (based on Api V3) | ||
# An (unofficial) Github command line client | ||
|
||
This command line client is based on Github API V3. | ||
|
||
## What it does | ||
|
||
You can manipulate following Github resources: | ||
|
||
- deployment | ||
- deployment_status | ||
- release | ||
|
||
## What it will (probably) never do | ||
|
||
Managing resources like pull requests, issues or repositories life cycle and settings. | ||
|
||
Some very good tools like [hub](https://github.com/github/hub) or [terraform's github provider](https://www.terraform.io/docs/providers/github/index.html) are already great at doing that. | ||
|
||
## Why another Github client? | ||
|
||
The goal is to have a convenient, lightweight tool to use inside github [actions v2](https://github.com/features/actions) workflows. | ||
|
||
Some use cases that motivated the creation of this tool were: | ||
|
||
```shell | ||
# Append some deploy button inside a release note | ||
printf "%s\nDEPLOY_BUTTON_CODE" $(github release get ID | jq .body) | \ | ||
github release edit ID --body - | ||
|
||
# Create a production deployment and corresponding status | ||
DEPLOYMENT_ID=$( | ||
github deployment create \ | ||
--environment production \ | ||
--task deploy:migration \ | ||
$GITHUB_REF | ||
) | ||
github deployment_status create $DEPLOYMENT_ID in_progress | ||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
package cmd | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"log" | ||
"os" | ||
"strconv" | ||
|
||
"github.com/google/go-github/v27/github" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
) | ||
|
||
var deployment = &cobra.Command{ | ||
Use: "deployment", | ||
Short: "Deployment", | ||
Run: func(cmd *cobra.Command, args []string) { | ||
cmd.Help() | ||
os.Exit(0) | ||
}, | ||
} | ||
|
||
var deploymentGetCmd = &cobra.Command{ | ||
Use: "get ID", | ||
Short: "Get a deployment", | ||
Aliases: []string{"g"}, | ||
Args: cobra.ExactArgs(1), | ||
Run: func(cmd *cobra.Command, args []string) { | ||
deploymentID, err := strconv.ParseInt(args[0], 10, 64) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
deployment, _, err := client.Repositories.GetDeployment(ctx, owner, repository, deploymentID) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
json, err := json.MarshalIndent(deployment, "", " ") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
fmt.Printf("%s\n", json) | ||
}, | ||
} | ||
|
||
var deploymentListCmd = &cobra.Command{ | ||
Use: "list", | ||
Short: "List deployments", | ||
Aliases: []string{"ls"}, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
viper.BindPFlags(cmd.PersistentFlags()) | ||
var deploymentsListOptions github.DeploymentsListOptions | ||
err := viper.Unmarshal(&deploymentsListOptions) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
var listOptions github.ListOptions | ||
err = viper.Unmarshal(&listOptions) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
deploymentsListOptions.ListOptions = listOptions | ||
|
||
deployments, _, err := client.Repositories.ListDeployments(ctx, owner, repository, &deploymentsListOptions) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
json, err := json.MarshalIndent(deployments, "", " ") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
fmt.Printf("%s\n", json) | ||
}, | ||
} | ||
|
||
var deploymentCreateCmd = &cobra.Command{ | ||
Use: "create REF", | ||
Short: "Create a deployment", | ||
Aliases: []string{"c"}, | ||
Args: cobra.ExactArgs(1), | ||
Run: func(cmd *cobra.Command, args []string) { | ||
viper.BindPFlags(cmd.PersistentFlags()) | ||
|
||
var deploymentRequest github.DeploymentRequest | ||
err := viper.Unmarshal(&deploymentRequest) | ||
deploymentRequest.Ref = &args[0] | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
deployment, _, err := client.Repositories.CreateDeployment(ctx, owner, repository, &deploymentRequest) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
fmt.Printf("Successfully created deployment: %v\n", deployment.GetID()) | ||
}, | ||
} | ||
|
||
func init() { | ||
deployment.Aliases = []string{"d"} | ||
|
||
deployment.AddCommand(deploymentCreateCmd) | ||
deploymentCreateCmd.PersistentFlags().StringP("task", "t", "deploy", "Specifies a task to execute (e.g., deploy or deploy:migrations).") | ||
deploymentCreateCmd.PersistentFlags().BoolP("autoMerge", "a", true, "Attempts to automatically merge the default branch into the requested ref, if it's behind the default branch.") | ||
deploymentCreateCmd.PersistentFlags().StringSliceP("requiredContexts", "c", []string{}, "The status contexts to verify against commit status checks. If you omit this parameter, GitHub verifies all unique contexts before creating a deployment. To bypass checking entirely, pass an empty array. Defaults to all unique contexts.") | ||
deploymentCreateCmd.PersistentFlags().StringP("payload", "p", "", "JSON payload with extra information about the deployment.") | ||
deploymentCreateCmd.PersistentFlags().StringP("environment", "e", "production", "Name for the target deployment environment (e.g., production, staging, qa).") | ||
deploymentCreateCmd.PersistentFlags().StringP("description", "d", "", "Short description of the deployment.") | ||
deploymentCreateCmd.PersistentFlags().Bool("transientEnvironment", false, "Specifies if the given environment is specific to the deployment and will no longer exist at some point in the future.") | ||
deploymentCreateCmd.PersistentFlags().BoolP("productionEnvironment", "i", true, "Specifies if the given environment is one that end-users directly interact with. Default: true when environment is production and false otherwise.") | ||
|
||
deployment.AddCommand(deploymentGetCmd) | ||
|
||
deployment.AddCommand(deploymentListCmd) | ||
deploymentListCmd.PersistentFlags().StringP("sha", "s", "", "sha of the deployment") | ||
deploymentListCmd.PersistentFlags().StringP("ref", "", "", "list deployments for a given ref.") | ||
deploymentListCmd.PersistentFlags().StringP("task", "t", "", "list deployments for a given task.") | ||
deploymentListCmd.PersistentFlags().StringP("environment", "e", "", "list deployments for a given environment.") | ||
deploymentListCmd.PersistentFlags().IntP("page", "p", 1, "for paginated result sets, page of results to retrieve.") | ||
deploymentListCmd.PersistentFlags().IntP("perPage", "l", 10, "for paginated result sets, the number of results to include per page.") | ||
|
||
rootCmd.AddCommand(deployment) | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
package cmd | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"log" | ||
"os" | ||
"strconv" | ||
|
||
"github.com/google/go-github/v27/github" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
) | ||
|
||
var deploymentStatus = &cobra.Command{ | ||
Use: "deployment_status", | ||
Short: "Deployment Status", | ||
Run: func(cmd *cobra.Command, args []string) { | ||
cmd.Help() | ||
os.Exit(0) | ||
}, | ||
} | ||
|
||
var deploymentStatusListCmd = &cobra.Command{ | ||
Use: "list ID", | ||
Short: "List deployment statuses", | ||
Aliases: []string{"ls"}, | ||
Args: cobra.ExactArgs(1), | ||
Run: func(cmd *cobra.Command, args []string) { | ||
deploymentID, err := strconv.ParseInt(args[0], 10, 64) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
pFlags := cmd.PersistentFlags() | ||
page, err := pFlags.GetInt("page") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
perPage, err := pFlags.GetInt("perPage") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
listOptions := github.ListOptions{Page: page, PerPage: perPage} | ||
|
||
deploymentStatuses, _, err := client.Repositories.ListDeploymentStatuses(ctx, owner, repository, deploymentID, &listOptions) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
json, err := json.MarshalIndent(deploymentStatuses, "", " ") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
fmt.Printf("%s\n", json) | ||
}, | ||
} | ||
|
||
var deploymentStatusGetCmd = &cobra.Command{ | ||
Use: "create DEPLOYMENT_ID DEPLOYMENT_STATUS_ID", | ||
Short: "Get a single deployment status", | ||
Aliases: []string{"g"}, | ||
Args: cobra.ExactArgs(2), | ||
Run: func(cmd *cobra.Command, args []string) { | ||
deploymentID, err := strconv.ParseInt(args[0], 10, 64) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
deploymentStatusID, err := strconv.ParseInt(args[1], 10, 64) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
deploymentStatus, _, err := client.Repositories.GetDeploymentStatus(ctx, owner, repository, deploymentID, deploymentStatusID) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
json, err := json.MarshalIndent(deploymentStatus, "", " ") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
fmt.Printf("%s\n", json) | ||
}, | ||
} | ||
|
||
func isValidState(state string) error { | ||
switch state { | ||
case | ||
"error", | ||
"failure", | ||
"inactive", | ||
"in_progress", | ||
"queued", | ||
"pending": | ||
return nil | ||
} | ||
|
||
return errors.New("invalid state: should be one of error, failure, inactive, in_progress, queued or pending") | ||
} | ||
|
||
var deploymentStatusCreateCmd = &cobra.Command{ | ||
Use: "create DEPLOYMENT_ID STATE", | ||
Short: "Create a deployment status", | ||
Aliases: []string{"c"}, | ||
Args: cobra.ExactArgs(2), | ||
Run: func(cmd *cobra.Command, args []string) { | ||
deploymentID, err := strconv.ParseInt(args[0], 10, 64) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
err = isValidState(args[1]) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
state := args[1] | ||
|
||
viper.BindPFlags(cmd.PersistentFlags()) | ||
var deploymentStatusRequest github.DeploymentStatusRequest | ||
err = viper.Unmarshal(&deploymentStatusRequest) | ||
deploymentStatusRequest.State = &state | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
deploymentStatus, _, err := client.Repositories.CreateDeploymentStatus(ctx, owner, repository, deploymentID, &deploymentStatusRequest) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
fmt.Printf("%v\n", deploymentStatus.GetID()) | ||
}, | ||
} | ||
|
||
func init() { | ||
deploymentStatus.AddCommand(deploymentStatusGetCmd) | ||
|
||
deploymentStatus.AddCommand(deploymentStatusListCmd) | ||
deploymentStatusListCmd.PersistentFlags().IntP("page", "p", 1, "for paginated result sets, page of results to retrieve.") | ||
deploymentStatusListCmd.PersistentFlags().IntP("perPage", "l", 10, "for paginated result sets, the number of results to include per page.") | ||
|
||
deploymentStatus.AddCommand(deploymentStatusCreateCmd) | ||
deploymentStatusCreateCmd.PersistentFlags().String("logURL", "", "The full URL of the deployment's output.") | ||
deploymentStatusCreateCmd.PersistentFlags().StringP("description", "d", "", "A short description of the status. The maximum description length is 140 characters.") | ||
deploymentStatusCreateCmd.PersistentFlags().StringP("environment", "e", "", "Name for the target deployment environment, which can be changed when setting a deploy status. For example, production, staging, or qa.") | ||
deploymentStatusCreateCmd.PersistentFlags().StringP("environmentURL", "u", "", "for paginated result sets, page of results to retrieve.") | ||
deploymentStatusCreateCmd.PersistentFlags().BoolP("autoInactive", "a", true, "Adds a new inactive status to all prior non-transient, non-production environment deployments with the same repository and environment name as the created status's deployment. An inactive status is only added to deployments that had a success state.") | ||
|
||
deploymentStatus.Aliases = []string{"ds"} | ||
|
||
rootCmd.AddCommand(deploymentStatus) | ||
} |
Oops, something went wrong.