Skip to content

Commit

Permalink
chore: codegen for doc
Browse files Browse the repository at this point in the history
  • Loading branch information
giautm committed Jan 1, 2025
1 parent 040de28 commit 90412ce
Show file tree
Hide file tree
Showing 9 changed files with 348 additions and 11 deletions.
17 changes: 11 additions & 6 deletions atlasaction/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -1240,23 +1240,28 @@ func RenderTemplate(name string, data any) (string, error) {
return buf.String(), nil
}

// toEnvName converts the given string to an environment variable name.
func toEnvName(s string) string {
// ToEnvName converts the given string to an environment variable name.
func ToEnvName(s string) string {
return strings.ToUpper(strings.NewReplacer(
" ", "_", "-", "_", "/", "_",
).Replace(s))
}

// toInputVarName converts the given string to an input variable name.
func toInputVarName(input string) string {
return fmt.Sprintf("ATLAS_INPUT_%s", toEnvName(input))
// ToInputVarName converts the given string to an input variable name.
func ToInputVarName(input string) string {
return fmt.Sprintf("ATLAS_INPUT_%s", ToEnvName(input))
}

// ToInputVarName converts the given string to an input variable name.
func ToOutputVarName(action, output string) string {
return "ATLAS_OUTPUT_" + ToEnvName(action+"_"+output)
}

// toOutputVar converts the given values to an output variable.
// The action and output are used to create the output variable name with the format:
// ATLAS_OUTPUT_<ACTION>_<OUTPUT>="<value>"
func toOutputVar(action, output, value string) string {
return fmt.Sprintf("ATLAS_OUTPUT_%s=%q", toEnvName(action+"_"+output), value)
return fmt.Sprintf("%s=%q", ToOutputVarName(action, output), value)
}

// fprintln writes the given values to the file using fmt.Fprintln.
Expand Down
2 changes: 1 addition & 1 deletion atlasaction/bitbucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func (a *bbPipe) GetTriggerContext(context.Context) (*TriggerContext, error) {

// GetInput implements the Action interface.
func (a *bbPipe) GetInput(name string) string {
return strings.TrimSpace(a.getenv(toInputVarName(name)))
return strings.TrimSpace(a.getenv(ToInputVarName(name)))
}

// SetOutput implements Action.
Expand Down
4 changes: 2 additions & 2 deletions atlasaction/circleci_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ func (a *circleCIOrb) Getenv(key string) string {

// GetInput implements the Action interface.
func (a *circleCIOrb) GetInput(name string) string {
v := a.getenv(toInputVarName(name))
v := a.getenv(ToInputVarName(name))
if v == "" {
// TODO: Remove this fallback once all the actions are updated.
v = a.getenv(toEnvName("INPUT_" + name))
v = a.getenv(ToEnvName("INPUT_" + name))
}
return strings.TrimSpace(v)
}
Expand Down
2 changes: 1 addition & 1 deletion atlasaction/gitlab_ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (a *gitlabCI) Getenv(key string) string {

// GetInput implements the Action interface.
func (a *gitlabCI) GetInput(name string) string {
return strings.TrimSpace(a.getenv(toInputVarName(name)))
return strings.TrimSpace(a.getenv(ToInputVarName(name)))
}

// SetOutput implements the Action interface.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module ariga.io/atlas-action

go 1.23
go 1.24rc1

require (
ariga.io/atlas v0.21.2-0.20240418081819-02b3f6239b04
Expand Down
119 changes: 119 additions & 0 deletions tools/gen/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package main

import (
"cmp"
"errors"
"io"
"io/fs"
"iter"
"maps"
"os"
"slices"
"strings"

"gopkg.in/yaml.v3"
)

func main() {
wd, err := os.Getwd()
if err != nil {
panic(err)
}
if err := process(wd); err != nil {
panic(err)
}
}

func process(path string) error {
fsys := os.DirFS(path)
files, err := fs.Glob(fsys, "**/*/action.yml")
if err != nil {
return err
}
actions := make([]actionSpec, len(files))
for i, f := range files {
if err := actions[i].fromPath(fsys, f); err != nil {
return err
}
}
slices.SortFunc(actions, func(i, j actionSpec) int {
return cmp.Compare(i.ID, j.ID)
})
return readmeMarkdown(os.Stdout, actions)
}

func readmeMarkdown(w io.Writer, actions []actionSpec) error {
return templates.ExecuteTemplate(w, "bitbucket.md", actions)
}

type (
actionSpec struct {
ID string `yaml:"-"`
Description string `yaml:"description"`
Name string `yaml:"name"`
Inputs map[string]actionInput `yaml:"inputs"`
Outputs map[string]actionOutput `yaml:"outputs"`
}
actionInput struct {
Description string `yaml:"description"`
Default string `yaml:"default"`
Required bool `yaml:"required"`
}
actionOutput struct {
Description string `yaml:"description"`
}
)

func (a *actionSpec) fromPath(fsys fs.FS, path string) error {
f, err := fsys.Open(path)
if err != nil {
return err
}
defer f.Close()
if err = yaml.NewDecoder(f).Decode(a); err != nil {
return err
}
if id, ok := strings.CutSuffix(path, "/action.yml"); ok {
a.ID = strings.Trim(id, "/")
return nil
}
return errors.New("gen: invalid action.yml path")
}

func (a *actionSpec) SortedInputs() iter.Seq2[string, actionInput] {
orders := []string{"working-directory", "config", "env", "vars", "dev-url"}
return func(yield func(string, actionInput) bool) {
keys := slices.SortedFunc(maps.Keys(a.Inputs), ComparePriority(orders))
for _, k := range keys {
if !yield(k, a.Inputs[k]) {
return
}
}
}
}

func (a *actionSpec) SortedOutputs() iter.Seq2[string, actionOutput] {
return func(yield func(string, actionOutput) bool) {
for _, k := range slices.Sorted(maps.Keys(a.Outputs)) {
if !yield(k, a.Outputs[k]) {
return
}
}
}
}

func ComparePriority[T cmp.Ordered](ordered []T) func(T, T) int {
return func(x, y T) int {
switch xi, yi := slices.Index(ordered, x), slices.Index(ordered, y); {
case xi != -1 && yi != -1:
return cmp.Compare(xi, yi)
case yi != -1:
return -1
case xi != -1:
return +1
default:
// fallback to default comparison
return cmp.Compare(x, y)
}
}
}
81 changes: 81 additions & 0 deletions tools/gen/template/bitbucket.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
title: Bitbucket Pipes
id: bitbucket-pipes
slug: /integrations/bitbucket-pipes
---

import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'

// TODO: Write introduce

{{ range . }}

## `{{ .ID }}`

{{ .Description }}

{{ $tmpl := printf "usage/bitbucket/%s" .ID -}}
{{- if hasTemplate $tmpl -}}
{{- xtemplate $tmpl . -}}
{{- end -}}

{{ if .Inputs }}
### Inputs

* `ATLAS_ACTION` - (Required) always is `{{ .ID }}`.
* `ATLAS_TOKEN` - (Optional) to authenticate with Atlas Cloud.
* `BITBUCKET_ACTION_TOKEN` - (Optional) Bitbucket access token to post comment on the PR.
{{- range $name, $item := .SortedInputs }}
* `{{ $name | inputvar }}` - {{ if not $item.Required }}(Optional) {{end}}{{ $item.Description | trimnl | nl2sp }}
{{- end }}
{{ end -}}
{{ if .Outputs }}
### Outputs

The outputs are written into the `.atlas-action/outputs.sh`, we can load it for the next step using the `source` command.
{{ $action := . }}
{{ range $name, $item := .SortedOutputs }}
* `{{ $name | outputvar $action.ID }}` - {{ $item.Description | trimnl | nl2sp }}
{{- end }}
{{- end }}
{{ end }}
{{- define "usage/bitbucket/schema/plan" -}}
### Usage

Add `bitbucket-pipelines.yml` to your repo with the following contents:

<Tabs
defaultValue="mysql"
values={[
{{- range $value, $item := dockers }}
{label: "{{ $item.Label }}", value: "{{ $value }}"},
{{- end }}
]}>

{{- $action := . -}}
{{- range $value, $item := dockers }}
<TabItem value="{{ $value }}">

```yaml
image: atlassian/default-image:3
pipelines:
branches:
master:
- step:
name: "{{ $action.Description }}"
script:
- name: "{{ $action.Name }}"
pipe: docker://arigaio/atlas-action:master
variables:
ATLAS_ACTION: "{{ $action.ID }}" # Required
ATLAS_TOKEN: ${ATLAS_TOKEN}
BITBUCKET_ACCESS_TOKEN: ${BITBUCKET_ACCESS_TOKEN}
ATLAS_INPUT_DEV_URL: "{{ $item.DevURL }}"
- source .atlas-action/outputs.sh
```
</TabItem>
{{- end }}
</Tabs>
{{- end -}}
19 changes: 19 additions & 0 deletions tools/gen/template/github.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{{ range . }}
### `ariga/atlas-action/{{ .ID }}`

{{ .Description }}
{{ if .Inputs }}
#### Inputs

All inputs are optional as they may be specified in the Atlas configuration file.
{{ range $name, $item := .SortedInputs }}
* `{{ $name }}` - {{ if not $item.Required }}(Optional) {{end}}{{ $item.Description | trimnl | nl2sp }}
{{- end }}
{{ end -}}
{{ if .Outputs }}
#### Outputs
{{ range $name, $item := .SortedOutputs }}
* `{{ $name }}` - {{ $item.Description | trimnl | nl2sp }}
{{- end }}
{{ end }}
{{ end }}
Loading

0 comments on commit 90412ce

Please sign in to comment.