Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 6 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,9 @@ steps:
TARGET_STACK: # If specified, will only run deployments for the specified stack (optional)
GLOBAL_CONFIG: # Path to the global gitops config (optional if app config is provided)
VALUE: # Value to update the files in the config repository (required)
GH_TOKEN: # Github PAT with proper permissions (optional if GH_APP_KEY is provided)
GH_APP_KEY: # Github App private key (optional if GH_TOKEN is provided)
GH_APP_ID: # Github App ID (optional if GH_TOKEN is provided)
GH_APP_INSTALLATION_ID: # Github App Installation ID (optional if GH_TOKEN is provided)
GH_APP_KEY: # Github App private key
GH_APP_ID: # Github App ID
GH_APP_INSTALLATION_ID: # Github App Installation ID
GIT_COMMIT_AUTHOR_NAME: # Name of the commit author (optional)
GIT_COMMIT_AUTHOR_EMAIL: # Email of the commit author (optional)
PR_TITLE: # Title of the PR in the config repository (optional)
Expand Down Expand Up @@ -330,23 +329,16 @@ jobs:
run: |
echo "service=$(echo ${{ matrix.service-path }} | sed 's/services\///g')" >> "${GITHUB_OUTPUT}"

- id: create_token
uses: tibdex/github-app-token@v2
with:
app_id: 12345
private_key: ${{ secrets.PRIVATE_KEY }}

- name: Deploy
uses: docker://ghcr.io/geode-io/gitops-tools:latest
env:
GH_TOKEN: ${{ steps.create_token.outputs.token }}
GH_APP_KEY: # Github App private key
GH_APP_ID: # Github App ID
GH_APP_INSTALLATION_ID: # Github App Installation ID
APP_NAME: ${{ steps.service-name.outputs.service }}
APP_CONFIG: ${{ matrix.service-path }}/gitops-actions.yaml # load the service specific config if exists
TARGET_STACK: dev # if you want to deploy to a specific stack
VALUE: ${{ github.sha }}
GLOBAL_CONFIG: gitops-actions.yaml
GIT_COMMIT_AUTHOR_NAME: "geode-actions-bot"
```

> [!TIP]
> It is recommended to use a Github App to authenticate with Github API. You can use the `tibdex/github-app-token` action to create a token for the Github App and use it in the action.
3 changes: 0 additions & 3 deletions cmd/gitops-actions/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ func main() {
appConfig := kingpin.Flag("app-config", "Path to the gitops app config file. required if app-name is not provided").Envar("APP_CONFIG").String()
value := kingpin.Flag("value", "Value to update in the config files").Required().Envar("VALUE").String()
targetStack := kingpin.Flag("target-stack", "Target stack to update").Envar("TARGET_STACK").String()
ghToken := kingpin.Flag("gh-token", "Github Token for git and Github operations").Envar("GH_TOKEN").String()
ghAppKey := kingpin.Flag("gh-app-key", "Github App Key for Github operations").Envar("GH_APP_KEY").String()
ghAppId := kingpin.Flag("gh-app-id", "Github App ID for Github operations").Envar("GH_APP_ID").Int64()
ghAppInstallationId := kingpin.Flag("gh-app-installation-id", "Github App Installation ID for Github operations").Envar("GH_APP_INSTALLATION_ID").Int64()
Expand Down Expand Up @@ -53,7 +52,6 @@ func main() {

actions.Infof("initializing git client ...")
git, err := git.NewClient(&git.ClientOpts{
Token: *ghToken,
AppKey: *ghAppKey,
AppId: *ghAppId,
AppInstallationId: *ghAppInstallationId,
Expand All @@ -66,7 +64,6 @@ func main() {

actions.Infof("initializing github client ...")
gh, err := github.NewClient(&github.ClientOpts{
Token: *ghToken,
AppKey: *ghAppKey,
AppId: *ghAppId,
AppInstallationId: *ghAppInstallationId,
Expand Down
27 changes: 11 additions & 16 deletions internal/git/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

type ClientOpts struct {
Token, AppKey string
AppKey string
AppId, AppInstallationId int64
AuthorName, AuthorEmail string
}
Expand Down Expand Up @@ -41,21 +41,16 @@ func NewClient(opts *ClientOpts) (*Client, error) {
authorName: opts.AuthorName,
authorEmail: opts.AuthorEmail,
}
token := opts.Token
if token == "" {
client.authMethod = "app"
client.ctx = context.Background()
itr, err := ghinstallation.NewKeyFromFile(net.DefaultTransport, opts.AppId, opts.AppInstallationId, opts.AppKey)
if err != nil {
return nil, err
}
client.itr = itr
token, err = itr.Token(client.ctx)
if err != nil {
return nil, err
}
} else {
client.authMethod = "token"
client.authMethod = "app"
client.ctx = context.Background()
itr, err := ghinstallation.New(net.DefaultTransport, opts.AppId, opts.AppInstallationId, []byte(opts.AppKey))
if err != nil {
return nil, err
}
client.itr = itr
token, err := itr.Token(client.ctx)
if err != nil {
return nil, err
}
client.auth = &http.BasicAuth{
Username: "gitops-actions",
Expand Down
43 changes: 10 additions & 33 deletions internal/github/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ package github

import (
"context"
"fmt"
"net/http"
"time"

actions "github.com/sethvargo/go-githubactions"

"github.com/bradleyfalzon/ghinstallation/v2"
"github.com/google/go-github/v61/github"
"golang.org/x/oauth2"
)

var (
Expand All @@ -23,25 +21,17 @@ type Client struct {
}

type ClientOpts struct {
Token, AppKey string
AppKey string
AppId, AppInstallationId int64
}

func NewClient(opts *ClientOpts) (*Client, error) {
var err error
ctx := context.Background()
client := github.NewClient(nil)

if opts.Token != "" {
client, err = GetGHClient(opts, ctx, "pat")
if err != nil {
return nil, err
}
} else {
client, err = GetGHClient(opts, ctx, "app")
if err != nil {
return nil, err
}
client, err = GetGHClient(opts, ctx)
if err != nil {
return nil, err
}
c := &Client{
Client: client,
Expand All @@ -56,26 +46,13 @@ func NewClient(opts *ClientOpts) (*Client, error) {
return c, nil
}

func GetGHClient(opts *ClientOpts, ctx context.Context, clientType string) (*github.Client, error) {
switch clientType {
case "pat":
ctx := context.Background()
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: opts.Token},
)
tc := oauth2.NewClient(ctx, ts)
client := github.NewClient(tc)
return client, nil
case "app":
itr, err := ghinstallation.NewKeyFromFile(http.DefaultTransport, opts.AppId, opts.AppInstallationId, opts.AppKey)
if err != nil {
return nil, err
}
client := github.NewClient(&http.Client{Transport: itr})
return client, nil

func GetGHClient(opts *ClientOpts, ctx context.Context) (*github.Client, error) {
itr, err := ghinstallation.New(http.DefaultTransport, opts.AppId, opts.AppInstallationId, []byte(opts.AppKey))
if err != nil {
return nil, err
}
return nil, fmt.Errorf("invalid client type")
client := github.NewClient(&http.Client{Transport: itr})
return client, nil
}

func (c *Client) CheckRateLimit() error {
Expand Down