diff --git a/.gitignore b/.gitignore index 52ecbe5..eac53b2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .idea/ .env test.md +deployment-overview.md +deployment-overview.json diff --git a/README.md b/README.md index 4cf5953..b2bd4f2 100644 --- a/README.md +++ b/README.md @@ -35,17 +35,17 @@ go buid main.go -o deployment-overview ## Parrameters -| Paramter | Environment | Required | Default | Example | Description | -| --- | --- |-------|---------|-----------------------------------------------------------------------------|-------------------------------------------------------------------------------| -| --github-token | GITHUB_TOKEN | true | - | - | The GitHub Personal Access Token (PAT) | -| --environments | ENVIRONMENTS | true | - | dev,staging,prod | Environments to query. Comma separated list. | -| --organization | ORGANIZATION | true | - | myorga | The GitHub Organization to query for repositories. | -| --repositories | REPOSITORIES | true | - | frontend,backend | Repositories to query. Comma separated list. | -| --target-repository | TARGET_REPOSITORY | true | - | .github | The target repository to commit the result to. | -| --target-repository-file | TARGET_REPOSITORY_FILE | true | - | profile/README.md | The target repository file to commit the result to. | -| --verbose | VERBOSE | false | 1 | 0 | Verbosity level, 0=info, 1=debug. Overrides the environment variable VERBOSE. | -| --environment-links | ENVIRONMENT_LINKS | false | - | https://dev.example.com,https://staging.example.com,https://www.example.com | Links to the environments. Comma separated list. | -| --template-file | TEMPLATE_FILE | false | - | template/default.md | The template file to use. | +| Paramter | Environment | Required | Default | Example | Description | +| --- | --- |-------|--------------------------|-----------------------------------------------------------------------------|-------------------------------------------------------------------------------| +| --github-token | GITHUB_TOKEN | true | - | - | The GitHub Personal Access Token (PAT) | +| --environments | ENVIRONMENTS | true | - | dev,staging,prod | Environments to query. Comma separated list. | +| --organization | ORGANIZATION | true | - | myorga | The GitHub Organization to query for repositories. | +| --repositories | REPOSITORIES | true | - | frontend,backend | Repositories to query. Comma separated list. | +| --verbose | VERBOSE | false | 1 | 0 | Verbosity level, 0=info, 1=debug. Overrides the environment variable VERBOSE. | +| --environment-links | ENVIRONMENT_LINKS | false | - | https://dev.example.com,https://staging.example.com,https://www.example.com | Links to the environments. Comma separated list. | +| --template-file | TEMPLATE_FILE | false | - | template/default.md | The template file to use. | +| --target-json-file | TARGET_JSON_FILE | false | deployment-overview.json | - | The target file to write the result to as JSON. | +| --target-md-file | TARGET_MD_FILE | false | deployment-overview.md | - | The target file to write the result to as Markdown. | ## Use as GitHub Action @@ -65,7 +65,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Deployment overview - uses: prodyna/deployment-overview@v0.1 + uses: prodyna/deployment-overview@v0.2 with: organization: myorg target-repository: .github @@ -86,7 +86,6 @@ The PAT should be a Fine Grain PAT that belongs to the target organization and h | Permission | Access | | --- | --- | | Actions | Read | -| Contents | Read & Write | | Deployments | Read | | Environments | Read | | Metadata | Read | diff --git a/action.yaml b/action.yaml index f69e438..ed8bfbb 100644 --- a/action.yaml +++ b/action.yaml @@ -20,14 +20,6 @@ inputs: description: 'The verbosity level' required: true default: 1 - target-repository: - description: 'The repository where the overview will be written to' - required: true - default: '.github' - target-repository-file: - description: 'The file where the overview will be written to' - required: true - default: 'profile/README.md' github-token: description: 'The token to use for the GitHub API' required: true @@ -35,10 +27,14 @@ inputs: description: 'The title of the overview' required: true default: 'Deployment overview' - template-file: - description: 'The template file to use for the overview' - required: true - default: '/template/default.tpl' + targetJsonFile: + description: 'The file to write the JSON to' + required: false + default: 'deployment-overview.json' + targetMdFile: + description: 'The file to write the MD to' + required: false + default: 'deployment-overview.md' runs: using: 'docker' image: 'Dockerfile' @@ -48,8 +44,8 @@ runs: ENVIRONMENTS: ${{ inputs.environments }} ENVIRONMENT_LINKS: ${{ inputs.environment-links }} VERBOSE: ${{ inputs.verbose }} - TARGET_REPOSITORY: ${{ inputs.target-repository }} - TARGET_REPOSITORY_FILE: ${{ inputs.target-repository-file }} GITHUB_TOKEN: ${{ inputs.github-token }} TITLE: ${{ inputs.title }} TEMPLATE_FILE: ${{ inputs.template-file }} + TARGET_JSON_FILE: ${{ inputs.targetJsonFile }} + TARGET_MD_FILE: ${{ inputs.targetMdFile }} diff --git a/config/config.go b/config/config.go index 9cbc090..1295cea 100644 --- a/config/config.go +++ b/config/config.go @@ -12,35 +12,35 @@ import ( ) const ( - keyOrganization = "ORGANIZATION" - keyTargetRepository = "TARGET_REPOSITORY" - keyTargetRepositoryFile = "TARGET_REPOSITORY_FILE" - keyRepositories = "REPOSITORIES" - keyGithubToken = "GITHUB_TOKEN" - keyEnvironments = "ENVIRONMENTS" - keyEnvironmentLinks = "ENVIRONMENT_LINKS" - keyVerbose = "VERBOSE" - keyTemplateFile = "TEMPLATE_FILE" - keyTitle = "TITLE" + keyOrganization = "ORGANIZATION" + keyRepositories = "REPOSITORIES" + keyGithubToken = "GITHUB_TOKEN" + keyEnvironments = "ENVIRONMENTS" + keyEnvironmentLinks = "ENVIRONMENT_LINKS" + keyVerbose = "VERBOSE" + keyTemplateFile = "TEMPLATE_FILE" + keyTitle = "TITLE" + keyTargetJsonFile = "TARGET_JSON_FILE" + keyTargetMdFile = "TARGET_MD_FILE" ) type Config struct { - Organization string - TargetRepository string - TargetRepositoryFile string - Repositories string - Environments string - EnvironmentLinks string - GithubToken string - TemplateFile string - Title string + Organization string + TargetJsonFile string + TargetMdFile string + Repositories string + Environments string + EnvironmentLinks string + GithubToken string + TemplateFile string + Title string } func CreateConfig(ctx context.Context) (*Config, error) { c := Config{} flag.StringVar(&c.Organization, "organization", lookupEnvOrString(keyOrganization, ""), "The GitHub Organization to query for repositories.") - flag.StringVar(&c.TargetRepository, "target-repository", lookupEnvOrString(keyTargetRepository, ""), "The target repository to commit the result to.") - flag.StringVar(&c.TargetRepositoryFile, "target-repository-file", lookupEnvOrString(keyTargetRepositoryFile, ""), "The target repository file to commit the result to.") + flag.StringVar(&c.TargetJsonFile, "target-json-file", lookupEnvOrString(keyTargetJsonFile, "deployment-overview.json"), "The target json file to commit the result to.") + flag.StringVar(&c.TargetMdFile, "target-md-file", lookupEnvOrString(keyTargetMdFile, "deployment-overview.md"), "The target md file to commit the result to.") flag.StringVar(&c.Repositories, "repositories", lookupEnvOrString(keyRepositories, ""), "Repositories to query. Comma separated list.") flag.StringVar(&c.GithubToken, "github-token", lookupEnvOrString(keyGithubToken, ""), "The GitHub Token to use for authentication.") flag.StringVar(&c.Environments, "environments", lookupEnvOrString(keyEnvironments, ""), "Environments to query. Comma separated list.") @@ -64,9 +64,9 @@ func CreateConfig(ctx context.Context) (*Config, error) { "Repositories", c.RepositoriesAsList(), "Environments", c.EnvironmentsAsList(), "EnvironmentLinks", c.EnvironmentLinksAsList(), - "TargetRepository", c.TargetRepository, - "TargetRepositoryFile", c.TargetRepositoryFile, "TemplateFile", c.TemplateFile, + "TargetJsonFile", c.TargetJsonFile, + "TargetMdFile", c.TargetMdFile, "Title", c.Title) return &c, nil @@ -85,14 +85,6 @@ func (c *Config) Validate() error { return errors.New("Repositories is required") } - if c.TargetRepository == "" { - return errors.New("Target Repository is required") - } - - if c.TargetRepositoryFile == "" { - return errors.New("Target Repository File is required") - } - return nil } diff --git a/main.go b/main.go index da4ed53..a4299d1 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,6 @@ package main import ( "context" - "fmt" "github.com/google/go-github/v59/github" _ "github.com/google/go-github/v59/github" "github.com/prodyna/deployment-overview/config" @@ -59,7 +58,14 @@ func do() error { slog.ErrorContext(ctx, "Unable to render organization", "error", err) return err } - fmt.Printf("%s\n", json) + + slog.DebugContext(ctx, "Writing json to file", "file", c.TargetJsonFile) + err = publish.WriteFile(c.TargetJsonFile, json) + if err != nil { + slog.ErrorContext(ctx, "Unable to write json to file", "error", err) + return err + } + slog.InfoContext(ctx, "Wrote json to file", "file", c.TargetJsonFile) md, err := organization.RenderMarkdown(ctx, string(template)) if err != nil { @@ -67,11 +73,13 @@ func do() error { return err } - err = publish.PublishToGitHub(ctx, c, md, gh) + slog.DebugContext(ctx, "Writing md to file", "file", c.TargetMdFile) + err = publish.WriteFile(c.TargetMdFile, []byte(md)) if err != nil { - slog.ErrorContext(ctx, "Unable to publish to github", "error", err) + slog.ErrorContext(ctx, "Unable to write md to file", "error", err) return err } + slog.InfoContext(ctx, "Wrote md to file", "file", c.TargetMdFile) return nil } diff --git a/publish/publish.go b/publish/publish.go deleted file mode 100644 index 9bb6c58..0000000 --- a/publish/publish.go +++ /dev/null @@ -1,94 +0,0 @@ -package publish - -import ( - "context" - "fmt" - "github.com/google/go-github/v59/github" - "github.com/prodyna/deployment-overview/config" - "log/slog" -) - -func PublishToGitHub(ctx context.Context, c *config.Config, md string, gh *github.Client) (err error) { - // commit to github using the API - slog.InfoContext(ctx, "Committing to github", "repository", c.TargetRepository, "organization", c.Organization, "file", c.TargetRepositoryFile) - slog.DebugContext(ctx, "Getting target repository", "repository", c.TargetRepository, "organization", c.Organization) - repo, _, err := gh.Repositories.Get(ctx, c.Organization, c.TargetRepository) - if err != nil { - slog.ErrorContext(ctx, "Unable to get target repository", "error", err, "repository", c.TargetRepository, "organization", c.Organization) - return err - } - slog.DebugContext(ctx, "Default branch", "branch", *repo.DefaultBranch, "repository", c.TargetRepository, "organization", c.Organization) - defaultBranch := *repo.DefaultBranch - - slog.DebugContext(ctx, "Getting branch", "branch", defaultBranch, "repository", c.TargetRepository, "organization", c.Organization) - branch, _, err := gh.Repositories.GetBranch(ctx, c.Organization, c.TargetRepository, defaultBranch, 0) - if err != nil { - slog.ErrorContext(ctx, "Unable to get branch", "error", err, "branch", defaultBranch) - return err - } - slog.DebugContext(ctx, "Branch", "branch", branch, "repository", c.TargetRepository, "organization", c.Organization) - - // create blob - slog.DebugContext(ctx, "Creating blob", "repository", c.TargetRepository, "organization", c.Organization, "file", c.TargetRepositoryFile) - blob, _, err := gh.Git.CreateBlob(ctx, c.Organization, c.TargetRepository, &github.Blob{ - Content: &md, - Size: github.Int(len(md)), - }) - if err != nil { - slog.ErrorContext(ctx, "Unable to create blob", "error", err) - return err - } - slog.DebugContext(ctx, "Blob created", "repository", c.TargetRepository, "organization", c.Organization) - - treeEntry := []*github.TreeEntry{ - { - Path: github.String(c.TargetRepositoryFile), - Mode: github.String("100644"), - Type: github.String("blob"), - SHA: blob.SHA, - }, - } - - // create tree - slog.DebugContext(ctx, "Creating tree", "repository", c.TargetRepository, "organization", c.Organization) - tree, _, err := gh.Git.CreateTree(ctx, c.Organization, c.TargetRepository, *branch.Commit.SHA, treeEntry) - if err != nil { - slog.ErrorContext(ctx, "Unable to create tree", "error", err, "repository", c.TargetRepository, "organization", c.Organization) - return err - } - slog.DebugContext(ctx, "Tree created", "repository", c.TargetRepository, "organization", c.Organization) - - // create commit - slog.DebugContext(ctx, "Creating commit", "repository", c.TargetRepository, "organization", c.Organization) - commit, _, err := gh.Git.CreateCommit(ctx, c.Organization, c.TargetRepository, &github.Commit{ - Message: github.String("Updated deployment overview"), - Tree: tree, - Parents: []*github.Commit{ - { - SHA: branch.Commit.SHA, - }, - }, - }, nil) - if err != nil { - slog.ErrorContext(ctx, "Unable to create commit", "error", err, "repository", c.TargetRepository, "organization", c.Organization) - return err - } - slog.DebugContext(ctx, "Commit created", "repository", c.TargetRepository, "organization", c.Organization) - - // update branch - slog.DebugContext(ctx, "Updating branch", "repository", c.TargetRepository, "organization", c.Organization) - _, _, err = gh.Git.UpdateRef(ctx, c.Organization, c.TargetRepository, &github.Reference{ - Ref: github.String(fmt.Sprintf("refs/heads/%s", defaultBranch)), - Object: &github.GitObject{ - SHA: commit.SHA, - }, - }, false) - if err != nil { - slog.ErrorContext(ctx, "Unable to update branch", "error", err, "repository", c.TargetRepository, "organization", c.Organization) - return err - } - slog.DebugContext(ctx, "Branch updated", "repository", c.TargetRepository, "organization", c.Organization) - slog.InfoContext(ctx, "Updated deployment overview", "repository", c.TargetRepository, "organization", c.Organization) - - return nil -} diff --git a/publish/write.go b/publish/write.go new file mode 100644 index 0000000..b584740 --- /dev/null +++ b/publish/write.go @@ -0,0 +1,25 @@ +package publish + +import "os" + +func WriteFile(file string, data []byte) error { + // Open file for writing + f, err := os.Create(file) + if err != nil { + return err + } + + // Write data to file + _, err = f.Write(data) + if err != nil { + return err + } + + // Close file + err = f.Close() + if err != nil { + return err + } + + return nil +} diff --git a/result/result.go b/result/result.go index 1c0ae3f..949895f 100644 --- a/result/result.go +++ b/result/result.go @@ -8,7 +8,6 @@ import ( "github.com/google/go-github/v59/github" "github.com/prodyna/deployment-overview/config" "log/slog" - "os" "strings" "text/template" "time" @@ -293,7 +292,6 @@ func (organization *Organization) RenderJson(ctx context.Context) (result []byte slog.ErrorContext(ctx, "Unable to render organization", "error", err) return nil, err } - os.Stdout.Write(output) return output, nil }