mirror of
https://github.com/hanzoai/pack.git
synced 2026-09-30 23:43:13 +00:00
fix: use containerd platform parsing to fix platform parsing (#277)
* docs: inline llm instructions into mise.toml * fix: use containerd platform parsing and remove custom implementation * refactor: use a helper to define the default platform when none is defined * test: platform unit tests * test: platform integration test * refactor: simplify integration test assertions * test: inline tests.json into platform integration tests * refactor: move platform parsing inside BuildWithBuildkitClient * test: merge platform tests into general integration tests * test: update snapshot * ci: add qemu to integration tests
This commit is contained in:
@@ -64,6 +64,10 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: go mod download
|
||||
|
||||
# required for integration tests that use multiple platforms
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Run test for ${{ matrix.example }}
|
||||
env:
|
||||
# without the GITHUB_TOKEN, mise will 403 us
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# What is Railpack
|
||||
|
||||
Zero-config application builder that automatically analyzes your code and turns
|
||||
it into a container image. It's the successor to Nixpacks, built on BuildKit
|
||||
it into a container image. It's built on BuildKit
|
||||
with support for Node, Python, Go, PHP, and more.
|
||||
|
||||
# Architecture
|
||||
@@ -15,13 +15,6 @@ with support for Node, Python, Go, PHP, and more.
|
||||
- **Providers**: Language-specific modules that detect project types (e.g. Node
|
||||
detects package.json) and generate appropriate build steps
|
||||
|
||||
# Bash commands
|
||||
|
||||
- `mise run build` - Build the CLI binary (`./bin/railpack`), use this instead of `go build`
|
||||
- `mise run check` - Run linting, formatting, and static analysis
|
||||
- `mise run test` - Run unit tests
|
||||
- `mise run test-integration` - Runs *all* integration tests. Never run this. Instead, only run the test that you are currently working on, e.g. `mise run test-integration -- -run "TestExamplesIntegration/config-file"`
|
||||
|
||||
# Code style
|
||||
|
||||
- Follow Go conventions and existing patterns in the codebase
|
||||
@@ -34,10 +27,13 @@ with support for Node, Python, Go, PHP, and more.
|
||||
|
||||
# Workflow
|
||||
|
||||
- Do not use `go` directly. Instead, inspect @mise.toml and use `mise run <task>` to run various dev lifecycle commands.
|
||||
- Be sure to run `mise run check` when you're done making code changes
|
||||
- Don't run tests manually unless instructed to do so
|
||||
- Run unit tests and a couple of relevant integration tests to verify your changes
|
||||
- Don't run tests manually using `go test` unless instructed to do so
|
||||
- If tests are failing that are unrelated to your changes, let me know and stop working.
|
||||
- Use the `cli` mise task to test your changes on a specific example project, i.e. `mise run cli -- --verbose build --show-plan examples/node-vite-react-router-spa/`
|
||||
- Never `git commit`
|
||||
- Do not run any write operations with `git`
|
||||
- Do not use `bin/railpack` instead use `mise run cli` (which is the development build of `railpack`)
|
||||
|
||||
# File Conventions
|
||||
|
||||
+7
-5
@@ -11,6 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/containerd/platforms"
|
||||
"github.com/moby/buildkit/client"
|
||||
_ "github.com/moby/buildkit/client/connhelper/dockercontainer"
|
||||
_ "github.com/moby/buildkit/client/connhelper/nerdctlcontainer"
|
||||
@@ -49,7 +50,7 @@ type BuildWithBuildkitClientOptions struct {
|
||||
ProgressMode string
|
||||
SecretsHash string
|
||||
Secrets map[string]string
|
||||
Platform BuildPlatform
|
||||
Platform string
|
||||
ImportCache string
|
||||
ExportCache string
|
||||
CacheKey string
|
||||
@@ -85,9 +86,10 @@ func BuildWithBuildkitClient(appDir string, plan *plan.BuildPlan, opts BuildWith
|
||||
return errors.New(buildkitInfoError)
|
||||
}
|
||||
|
||||
buildPlatform := opts.Platform
|
||||
if (buildPlatform == BuildPlatform{}) {
|
||||
buildPlatform = DetermineBuildPlatformFromHost()
|
||||
// Parse the platform string using our helper function
|
||||
buildPlatform, err := ParsePlatformWithDefaults(opts.Platform)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse platform '%s': %w", opts.Platform, err)
|
||||
}
|
||||
|
||||
llbState, image, err := ConvertPlanToLLB(plan, ConvertPlanOptions{
|
||||
@@ -175,7 +177,7 @@ func BuildWithBuildkitClient(appDir string, plan *plan.BuildPlan, opts BuildWith
|
||||
return fmt.Errorf("error creating FS: %w", err)
|
||||
}
|
||||
|
||||
log.Debugf("Building image for %s with BuildKit %s", buildPlatform.String(), info.BuildkitVersion.Version)
|
||||
log.Debugf("Building image for %s with BuildKit %s", platforms.Format(buildPlatform), info.BuildkitVersion.Version)
|
||||
|
||||
secretsMap := make(map[string][]byte)
|
||||
for k, v := range opts.Secrets {
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
type ConvertPlanOptions struct {
|
||||
BuildPlatform BuildPlatform
|
||||
BuildPlatform specs.Platform
|
||||
|
||||
// Hash of all the secrets values that can be used to invalidate the layer cache when a secret changes
|
||||
SecretsHash string
|
||||
@@ -34,7 +34,7 @@ const (
|
||||
)
|
||||
|
||||
func ConvertPlanToLLB(plan *p.BuildPlan, opts ConvertPlanOptions) (*llb.State, *Image, error) {
|
||||
platform := opts.BuildPlatform.ToPlatform()
|
||||
platform := opts.BuildPlatform
|
||||
|
||||
localState := llb.Local("context",
|
||||
llb.SharedKeyHint("local"),
|
||||
|
||||
+10
-18
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/moby/buildkit/frontend/gateway/client"
|
||||
gw "github.com/moby/buildkit/frontend/gateway/grpcclient"
|
||||
"github.com/moby/buildkit/util/appcontext"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/railwayapp/railpack/core/plan"
|
||||
)
|
||||
@@ -120,31 +121,22 @@ func readRailpackPlan(ctx context.Context, c client.Client) (*plan.BuildPlan, er
|
||||
return plan, nil
|
||||
}
|
||||
|
||||
// validatePlatform checks if the platform is supported and returns the corresponding BuildPlatform
|
||||
func validatePlatform(opts map[string]string) (BuildPlatform, error) {
|
||||
// validatePlatform checks if the platform is supported and returns the corresponding specs.Platform
|
||||
func validatePlatform(opts map[string]string) (specs.Platform, error) {
|
||||
platformStr := opts["platform"]
|
||||
if platformStr == "" {
|
||||
// Default to host platform if none specified
|
||||
return DetermineBuildPlatformFromHost(), nil
|
||||
}
|
||||
|
||||
// Error if multiple platforms are specified
|
||||
if strings.Contains(platformStr, ",") {
|
||||
return BuildPlatform{}, fmt.Errorf("multiple platforms are not supported, got: %s", platformStr)
|
||||
return specs.Platform{}, fmt.Errorf("multiple platforms are not supported, got: %s", platformStr)
|
||||
}
|
||||
|
||||
// Match against supported platforms
|
||||
switch platformStr {
|
||||
case PlatformLinuxAMD64.String():
|
||||
return PlatformLinuxAMD64, nil
|
||||
case PlatformLinuxARM64.String():
|
||||
return PlatformLinuxARM64, nil
|
||||
default:
|
||||
return BuildPlatform{}, fmt.Errorf("unsupported platform: %s. Must be one of: %s, %s",
|
||||
platformStr,
|
||||
PlatformLinuxAMD64.String(),
|
||||
PlatformLinuxARM64.String())
|
||||
// Parse the platform using our helper function
|
||||
platform, err := ParsePlatformWithDefaults(platformStr)
|
||||
if err != nil {
|
||||
return specs.Platform{}, fmt.Errorf("invalid platform format: %s. Must be one of: linux/amd64, linux/arm64, etc", platformStr)
|
||||
}
|
||||
|
||||
return platform, nil
|
||||
}
|
||||
|
||||
// Read a file from the build context
|
||||
|
||||
+28
-55
@@ -1,66 +1,39 @@
|
||||
package buildkit
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/containerd/platforms"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
type BuildPlatform struct {
|
||||
OS string
|
||||
Architecture string
|
||||
Variant string
|
||||
}
|
||||
|
||||
var (
|
||||
PlatformLinuxAMD64 = BuildPlatform{
|
||||
OS: "linux",
|
||||
Architecture: "amd64",
|
||||
}
|
||||
PlatformLinuxARM64 = BuildPlatform{
|
||||
OS: "linux",
|
||||
Architecture: "arm64",
|
||||
Variant: "v8",
|
||||
}
|
||||
)
|
||||
|
||||
func DetermineBuildPlatformFromHost() BuildPlatform {
|
||||
if runtime.GOARCH == "arm64" {
|
||||
return PlatformLinuxARM64
|
||||
}
|
||||
return PlatformLinuxAMD64
|
||||
}
|
||||
|
||||
func ParsePlatform(platformStr string) (BuildPlatform, error) {
|
||||
// ParsePlatformWithDefaults parses a platform string and returns the corresponding specs.Platform.
|
||||
// If the input is empty, it defaults to a Linux platform that matches the host architecture.
|
||||
//
|
||||
// This function handles the common case where we need to map host platforms to container platforms.
|
||||
// We cannot use platforms.DefaultSpec() directly because it returns the host platform
|
||||
// (e.g., darwin/arm64/v8 on macOS), but container base images only support Linux platforms.
|
||||
// Instead, we map the host architecture to the corresponding Linux container platform
|
||||
// to provide optimal performance while ensuring compatibility with container runtimes.
|
||||
//
|
||||
// Examples:
|
||||
// - "" -> linux/amd64 (on Intel hosts) or linux/arm64/v8 (on ARM hosts)
|
||||
// - "linux/amd64" -> linux/amd64
|
||||
// - "linux/arm64" -> linux/arm64
|
||||
// - "linux/arm64/v8" -> linux/arm64/v8
|
||||
func ParsePlatformWithDefaults(platformStr string) (specs.Platform, error) {
|
||||
if platformStr == "" {
|
||||
return DetermineBuildPlatformFromHost(), nil
|
||||
// Default to Linux platform for container builds
|
||||
// We cannot use platforms.DefaultSpec() directly because it returns the host platform
|
||||
// (e.g., darwin/arm64/v8 on macOS), but container base images only support Linux platforms.
|
||||
// Instead, we map the host architecture to the corresponding Linux container platform
|
||||
// to provide optimal performance while ensuring compatibility with container runtimes.
|
||||
hostPlatform := platforms.DefaultSpec()
|
||||
if hostPlatform.Architecture == "arm64" {
|
||||
return specs.Platform{OS: "linux", Architecture: "arm64", Variant: "v8"}, nil
|
||||
} else {
|
||||
return specs.Platform{OS: "linux", Architecture: "amd64"}, nil
|
||||
}
|
||||
}
|
||||
|
||||
platform, err := platforms.Parse(platformStr)
|
||||
if err != nil {
|
||||
return BuildPlatform{}, fmt.Errorf("invalid platform format: %s. Must be one of: linux/amd64, linux/arm64, etc", platformStr)
|
||||
}
|
||||
|
||||
return BuildPlatform{
|
||||
OS: platform.OS,
|
||||
Architecture: platform.Architecture,
|
||||
Variant: platform.Variant,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p BuildPlatform) String() string {
|
||||
if p.Variant != "" {
|
||||
return fmt.Sprintf("%s/%s/%s", p.OS, p.Architecture, p.Variant)
|
||||
}
|
||||
return fmt.Sprintf("%s/%s", p.OS, p.Architecture)
|
||||
}
|
||||
|
||||
func (p BuildPlatform) ToPlatform() specs.Platform {
|
||||
return specs.Platform{
|
||||
OS: p.OS,
|
||||
Architecture: p.Architecture,
|
||||
Variant: p.Variant,
|
||||
}
|
||||
// Parse the user-specified platform string
|
||||
return platforms.Parse(platformStr)
|
||||
}
|
||||
|
||||
+94
-20
@@ -2,70 +2,144 @@ package buildkit
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
func TestParsePlatform(t *testing.T) {
|
||||
func TestValidatePlatform(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expected BuildPlatform
|
||||
expected specs.Platform
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "empty string returns host platform",
|
||||
name: "empty string returns Linux platform",
|
||||
input: "",
|
||||
expected: func() BuildPlatform {
|
||||
return DetermineBuildPlatformFromHost()
|
||||
// When no platform is specified, we default to a Linux platform that matches
|
||||
// the host architecture. This ensures container compatibility while preserving
|
||||
// performance characteristics of the host system.
|
||||
expected: func() specs.Platform {
|
||||
platform, _ := ParsePlatformWithDefaults("")
|
||||
return platform
|
||||
}(),
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "linux/arm64/v8",
|
||||
input: "linux/arm64/v8",
|
||||
expected: BuildPlatform{
|
||||
expected: specs.Platform{
|
||||
OS: "linux",
|
||||
Architecture: "arm64",
|
||||
Variant: "v8",
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "linux/amd64",
|
||||
input: "linux/amd64",
|
||||
expected: specs.Platform{
|
||||
OS: "linux",
|
||||
Architecture: "amd64",
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "invalid input",
|
||||
input: "invalid",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "multiple platforms not supported",
|
||||
input: "linux/amd64,linux/arm64",
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := ParsePlatform(tt.input)
|
||||
got, err := ParsePlatformWithDefaults(tt.input)
|
||||
if tt.wantErr {
|
||||
if err == nil {
|
||||
t.Errorf("ParsePlatform() expected error but got none")
|
||||
t.Errorf("ParsePlatformWithDefaults() expected error but got none")
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("ParsePlatform() error = %v", err)
|
||||
t.Errorf("ParsePlatformWithDefaults() error = %v", err)
|
||||
return
|
||||
}
|
||||
if got != tt.expected {
|
||||
t.Errorf("ParsePlatform() = %v, want %v", got, tt.expected)
|
||||
if got.OS != tt.expected.OS || got.Architecture != tt.expected.Architecture || got.Variant != tt.expected.Variant {
|
||||
t.Errorf("ParsePlatformWithDefaults() = %v, want %v", got, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildPlatformString(t *testing.T) {
|
||||
platform := BuildPlatform{
|
||||
OS: "linux",
|
||||
Architecture: "arm64",
|
||||
Variant: "v8",
|
||||
func TestValidatePlatformWithMultiplePlatforms(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expected specs.Platform
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "empty string returns Linux platform",
|
||||
input: "",
|
||||
expected: func() specs.Platform {
|
||||
platform, _ := ParsePlatformWithDefaults("")
|
||||
return platform
|
||||
}(),
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "linux/arm64/v8",
|
||||
input: "linux/arm64/v8",
|
||||
expected: specs.Platform{
|
||||
OS: "linux",
|
||||
Architecture: "arm64",
|
||||
Variant: "v8",
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "linux/amd64",
|
||||
input: "linux/amd64",
|
||||
expected: specs.Platform{
|
||||
OS: "linux",
|
||||
Architecture: "amd64",
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "invalid input",
|
||||
input: "invalid",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "multiple platforms not supported",
|
||||
input: "linux/amd64,linux/arm64",
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
expected := "linux/arm64/v8"
|
||||
|
||||
got := platform.String()
|
||||
if got != expected {
|
||||
t.Errorf("BuildPlatform.String() = %v, want %v", got, expected)
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
opts := map[string]string{"platform": tt.input}
|
||||
got, err := validatePlatform(opts)
|
||||
if tt.wantErr {
|
||||
if err == nil {
|
||||
t.Errorf("validatePlatform() expected error but got none")
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("validatePlatform() error = %v", err)
|
||||
return
|
||||
}
|
||||
if got.OS != tt.expected.OS || got.Architecture != tt.expected.Architecture || got.Variant != tt.expected.Variant {
|
||||
t.Errorf("validatePlatform() = %v, want %v", got, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+2
-6
@@ -86,11 +86,7 @@ var BuildCommand = &cli.Command{
|
||||
|
||||
secretsHash := getSecretsHash(env)
|
||||
|
||||
platform, err := buildkit.ParsePlatform(cmd.String("platform"))
|
||||
if err != nil {
|
||||
return cli.Exit(err, 1)
|
||||
}
|
||||
|
||||
platformStr := cmd.String("platform")
|
||||
err = buildkit.BuildWithBuildkitClient(app.Source, buildResult.Plan, buildkit.BuildWithBuildkitClientOptions{
|
||||
ImageName: cmd.String("name"),
|
||||
DumpLLB: cmd.Bool("dump-llb"),
|
||||
@@ -99,7 +95,7 @@ var BuildCommand = &cli.Command{
|
||||
CacheKey: cmd.String("cache-key"),
|
||||
SecretsHash: secretsHash,
|
||||
Secrets: env.Variables,
|
||||
Platform: platform,
|
||||
Platform: platformStr,
|
||||
GitHubToken: os.Getenv("GITHUB_TOKEN"),
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"deploy": {
|
||||
"base": {
|
||||
"image": "ghcr.io/railwayapp/railpack-runtime:latest"
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"include": [
|
||||
"."
|
||||
],
|
||||
"step": "build"
|
||||
}
|
||||
],
|
||||
"startCommand": "sh start.sh"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"commands": [
|
||||
{
|
||||
"cmd": "chmod +x start.sh"
|
||||
}
|
||||
],
|
||||
"inputs": [
|
||||
{
|
||||
"image": "ghcr.io/railwayapp/railpack-runtime:latest"
|
||||
},
|
||||
{
|
||||
"include": [
|
||||
"."
|
||||
],
|
||||
"local": true
|
||||
}
|
||||
],
|
||||
"name": "build",
|
||||
"secrets": [
|
||||
"*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Output the container architecture
|
||||
uname -m
|
||||
@@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"expectedOutput": "x86_64",
|
||||
"platform": "linux/amd64"
|
||||
},
|
||||
{
|
||||
"expectedOutput": "aarch64",
|
||||
"platform": "linux/arm64"
|
||||
},
|
||||
{
|
||||
"expectedOutput": "aarch64",
|
||||
"platform": "linux/arm64/v8"
|
||||
}
|
||||
]
|
||||
@@ -25,6 +25,7 @@ var buildkitCacheExport = flag.String("buildkit-cache-export", "", "BuildKit cac
|
||||
|
||||
type TestCase struct {
|
||||
ExpectedOutput string `json:"expectedOutput"`
|
||||
Platform string `json:"platform"`
|
||||
Envs map[string]string `json:"envs"`
|
||||
ConfigFilePath string `json:"configFile"`
|
||||
JustBuild bool `json:"justBuild"`
|
||||
@@ -102,6 +103,7 @@ func TestExamplesIntegration(t *testing.T) {
|
||||
|
||||
if err := buildkit.BuildWithBuildkitClient(examplePath, buildResult.Plan, buildkit.BuildWithBuildkitClientOptions{
|
||||
ImageName: imageName,
|
||||
Platform: testCase.Platform,
|
||||
ImportCache: *buildkitCacheImport,
|
||||
ExportCache: *buildkitCacheExport,
|
||||
Secrets: testCase.Envs,
|
||||
@@ -117,7 +119,7 @@ func TestExamplesIntegration(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := runContainerWithTimeout(t, imageName, testCase.ExpectedOutput, testCase.Envs); err != nil {
|
||||
if err := runContainerWithTimeout(t, imageName, testCase.ExpectedOutput, testCase.Envs, testCase.Platform); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
@@ -131,7 +133,7 @@ func cmdDoneChan(cmd *exec.Cmd) chan error {
|
||||
return ch
|
||||
}
|
||||
|
||||
func runContainerWithTimeout(t *testing.T, imageName, expectedOutput string, envs map[string]string) error {
|
||||
func runContainerWithTimeout(t *testing.T, imageName, expectedOutput string, envs map[string]string, platformStr string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
@@ -140,6 +142,12 @@ func runContainerWithTimeout(t *testing.T, imageName, expectedOutput string, env
|
||||
|
||||
// Build docker run command with environment variables
|
||||
args := []string{"run", "--rm", "--name", containerName}
|
||||
|
||||
// Add platform specification if provided
|
||||
if platformStr != "" {
|
||||
args = append(args, "--platform", platformStr)
|
||||
}
|
||||
|
||||
for key, value := range envs {
|
||||
args = append(args, "-e", fmt.Sprintf("%s=%s", key, value))
|
||||
}
|
||||
|
||||
@@ -12,21 +12,28 @@ run = [
|
||||
[tasks.cli]
|
||||
run = "go run cmd/cli/main.go"
|
||||
|
||||
# build the CLI binary (`./bin/railpack`)
|
||||
[tasks.build]
|
||||
run = "go build -o bin/railpack cmd/cli/main.go"
|
||||
|
||||
[tasks.clean]
|
||||
run = "rm -rf bin dist docs/dist"
|
||||
|
||||
# run unit tests
|
||||
[tasks.test]
|
||||
run = "go test -short ./..."
|
||||
|
||||
# Runs *all* integration tests. It is extremely slow, do not run this locally.
|
||||
# Instead, only run the test that you are currently working on:
|
||||
# `mise run test-integration -- -run "TestExamplesIntegration/config-file"`
|
||||
[tasks.test-integration]
|
||||
run = "go test -v ./integration_tests"
|
||||
|
||||
# update all test snapshots
|
||||
[tasks.test-update-snapshots]
|
||||
run = "UPDATE_SNAPS=true go test -short ./..."
|
||||
|
||||
# linting, formatting, and static analysis
|
||||
[tasks.check]
|
||||
run = """
|
||||
go vet ./...
|
||||
|
||||
Reference in New Issue
Block a user