Skip to content

Commit 8085f7d

Browse files
committed
feat: add storybook to kres
Add storybook GH workflow to kres Signed-off-by: Edward Sammut Alessi <edward.sammutalessi@siderolabs.com>
1 parent e1a258d commit 8085f7d

4 files changed

Lines changed: 160 additions & 9 deletions

File tree

internal/config/constants.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,14 @@ const (
112112
// renovate: datasource=github-tags depName=docker/setup-buildx-action
113113
SetupBuildxActionVersion = "v4.1.0"
114114
SetupBuildxActionRef = "d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5"
115+
// SetupNodeActionVersion is the version of setup-node github action.
116+
// renovate: datasource=github-tags depName=actions/setup-node
117+
SetupNodeActionVersion = "v6.4.0"
118+
SetupNodeActionRef = "48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e"
119+
// ChromaticActionVersion is the version of the chromaui/action github action.
120+
// renovate: datasource=github-tags depName=chromaui/action
121+
ChromaticActionVersion = "v17.1.0"
122+
ChromaticActionRef = "8ad69a40dea06755a3c6db290f300a39e011433b"
115123
// SetupTerraformActionVersion is the version of setup terraform github action.
116124
// renovate: datasource=github-tags depName=hashicorp/setup-terraform
117125
SetupTerraformActionVersion = "v4.0.1"

internal/output/ghworkflow/types.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ type StrategyMatrix struct {
9898
Include []map[string]string `yaml:"include"`
9999
}
100100

101+
// JobEnvironment represents a GitHub Actions job-level deployment environment.
102+
type JobEnvironment struct {
103+
Name string `yaml:"name"`
104+
URL string `yaml:"url,omitempty"`
105+
}
106+
101107
// Job represents GitHub Actions job.
102108
type Job struct {
103109
Name string `yaml:"name,omitempty"`
@@ -108,6 +114,7 @@ type Job struct {
108114
Needs []string `yaml:"needs,omitempty"`
109115
Outputs map[string]string `yaml:"outputs,omitempty"`
110116
Services map[string]Service `yaml:"services,omitempty"`
117+
Environment *JobEnvironment `yaml:"environment,omitempty"`
111118
Steps []*JobStep `yaml:"steps"`
112119
}
113120

@@ -203,15 +210,16 @@ type Service struct {
203210

204211
// JobStep represents GitHub Actions job step.
205212
type JobStep struct {
206-
Name string `yaml:"name"`
207-
ID string `yaml:"id,omitempty"`
208-
If string `yaml:"if,omitempty"`
209-
Uses ActionRef `yaml:"uses,omitempty"`
210-
With map[string]string `yaml:"with,omitempty"`
211-
Env map[string]string `yaml:"env,omitempty"`
212-
Run string `yaml:"run,omitempty"`
213-
ContinueOnError bool `yaml:"continue-on-error,omitempty"`
214-
TimeoutMinutes int `yaml:"timeout-minutes,omitempty"`
213+
Name string `yaml:"name"`
214+
ID string `yaml:"id,omitempty"`
215+
If string `yaml:"if,omitempty"`
216+
Uses ActionRef `yaml:"uses,omitempty"`
217+
With map[string]string `yaml:"with,omitempty"`
218+
Env map[string]string `yaml:"env,omitempty"`
219+
Run string `yaml:"run,omitempty"`
220+
WorkingDirectory string `yaml:"working-directory,omitempty"`
221+
ContinueOnError bool `yaml:"continue-on-error,omitempty"`
222+
TimeoutMinutes int `yaml:"timeout-minutes,omitempty"`
215223
}
216224

217225
type SlackNotifyPayload struct {

internal/project/auto/js.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,5 +88,7 @@ func (builder *builder) BuildJS() error {
8888
builder.targets = append(builder.targets, build)
8989
builder.commonInputs = append(builder.commonInputs, build)
9090

91+
builder.proj.AddTarget(js.NewChromatic(builder.meta))
92+
9193
return nil
9294
}

internal/project/js/chromatic.go

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4+
5+
package js
6+
7+
import (
8+
"fmt"
9+
"strings"
10+
11+
"github.com/siderolabs/kres/internal/config"
12+
"github.com/siderolabs/kres/internal/dag"
13+
"github.com/siderolabs/kres/internal/output/ghworkflow"
14+
"github.com/siderolabs/kres/internal/project/meta"
15+
)
16+
17+
// Chromatic generates a standalone GitHub Actions workflow that publishes
18+
// Storybook snapshots to Chromatic on every push and pull request.
19+
type Chromatic struct {
20+
dag.BaseNode
21+
22+
meta *meta.Options
23+
24+
SOPSExtractKey string `yaml:"sopsExtractKey,omitempty"`
25+
Enabled bool `yaml:"enabled"`
26+
}
27+
28+
// NewChromatic creates a new Chromatic node.
29+
func NewChromatic(meta *meta.Options) *Chromatic {
30+
return &Chromatic{
31+
BaseNode: dag.NewBaseNode("chromatic"),
32+
meta: meta,
33+
}
34+
}
35+
36+
// CompileGitHubWorkflow implements ghworkflow.Compiler.
37+
func (c *Chromatic) CompileGitHubWorkflow(o *ghworkflow.Output) error {
38+
if !c.Enabled {
39+
return nil
40+
}
41+
42+
nodeVersion := strings.TrimSuffix(config.NodeContainerImageVersion, "-alpine")
43+
44+
checkoutStep := ghworkflow.Step("Checkout code").
45+
SetUsesWithComment(
46+
"actions/checkout@"+config.CheckOutActionRef,
47+
"version: "+config.CheckOutActionVersion,
48+
).
49+
SetWith("fetch-depth", "0")
50+
51+
setupNodeStep := ghworkflow.Step("Setup Node.js").
52+
SetUsesWithComment(
53+
"actions/setup-node@"+config.SetupNodeActionRef,
54+
"version: "+config.SetupNodeActionVersion,
55+
).
56+
SetWith("node-version", nodeVersion)
57+
58+
installStep := &ghworkflow.JobStep{
59+
Name: "Install dependencies",
60+
Run: "npm ci\n",
61+
WorkingDirectory: "frontend/",
62+
}
63+
64+
var getTokenStep *ghworkflow.JobStep
65+
66+
if c.SOPSExtractKey != "" {
67+
getTokenStep = &ghworkflow.JobStep{
68+
Name: "Get token",
69+
Run: fmt.Sprintf(
70+
"chromaticProjectToken=$(sops decrypt --extract='%s' .secrets.yaml)\n"+
71+
"echo \"::add-mask::${chromaticProjectToken}\"\n"+
72+
"echo \"CHROMATIC_PROJECT_TOKEN=${chromaticProjectToken}\" >> $GITHUB_ENV\n",
73+
c.SOPSExtractKey,
74+
),
75+
}
76+
}
77+
78+
chromaticStep := ghworkflow.Step("Run Chromatic").
79+
SetID("chromatic").
80+
SetUsesWithComment(
81+
"chromaui/action@"+config.ChromaticActionRef,
82+
"version: "+config.ChromaticActionVersion,
83+
).
84+
SetWith("projectToken", "${{ env.CHROMATIC_PROJECT_TOKEN }}").
85+
SetWith("workingDir", "frontend/")
86+
87+
steps := []*ghworkflow.JobStep{checkoutStep, setupNodeStep, installStep}
88+
if getTokenStep != nil {
89+
steps = append(steps, getTokenStep)
90+
}
91+
92+
steps = append(steps, chromaticStep)
93+
94+
o.AddWorkflow(
95+
"chromatic",
96+
&ghworkflow.Workflow{
97+
Name: "chromatic",
98+
Concurrency: ghworkflow.Concurrency{
99+
Group: "${{ github.workflow }}-${{ github.head_ref || github.run_id }}",
100+
CancelInProgress: true,
101+
},
102+
On: ghworkflow.On{
103+
Push: ghworkflow.Push{
104+
Branches: ghworkflow.Branches{
105+
c.meta.MainBranch,
106+
"release-*",
107+
},
108+
Tags: []string{"v*"},
109+
},
110+
PullRequest: ghworkflow.PullRequest{
111+
Branches: ghworkflow.Branches{
112+
c.meta.MainBranch,
113+
"release-*",
114+
},
115+
},
116+
},
117+
// https://www.chromatic.com/docs/github-actions/
118+
Jobs: map[string]*ghworkflow.Job{
119+
"chromatic": {
120+
Name: "Run chromatic",
121+
RunsOn: ghworkflow.NewRunsOnGroupLabel(ghworkflow.GenericRunner, ""),
122+
Environment: &ghworkflow.JobEnvironment{
123+
Name: "Storybook preview",
124+
URL: "${{ steps.chromatic.outputs.storybookUrl }}",
125+
},
126+
Steps: steps,
127+
},
128+
},
129+
},
130+
)
131+
132+
return nil
133+
}

0 commit comments

Comments
 (0)