diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml index 7b36333..bdef9c7 100644 --- a/.github/workflows/pages.yaml +++ b/.github/workflows/pages.yaml @@ -29,7 +29,7 @@ jobs: run: rm -rf /opt/hostedtoolcache - name: Checkout - uses: actions/checkout@v6.0.1 + uses: actions/checkout@v6 with: fetch-depth: 0 @@ -42,7 +42,7 @@ jobs: uses: actions/configure-pages@v5 - name: Upload Pages Artifacts - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@v4 with: path: './static' diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 7f521d7..8377aae 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -17,7 +17,7 @@ jobs: run: rm -rf /opt/hostedtoolcache - name: Checkout - uses: actions/checkout@v6.0.1 + uses: actions/checkout@v6 with: fetch-depth: 0 @@ -27,33 +27,33 @@ jobs: git config user.email "github-actions[bot]@users.noreply.github.com" - name: Set Up Go - uses: actions/setup-go@v6.1.0 + uses: actions/setup-go@v6 with: go-version-file: go.mod check-latest: true - name: Set Up QEMU - uses: docker/setup-qemu-action@v3.7.0 + uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3.11.1 + uses: docker/setup-buildx-action@v3 - name: Authenticate to GitHub Container Registry - uses: docker/login-action@v3.6.0 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - name: Authenticate to DockerHub Container Registry - uses: docker/login-action@v3.6.0 + uses: docker/login-action@v3 with: registry: docker.io username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v6.4.0 + uses: goreleaser/goreleaser-action@v6 with: distribution: goreleaser version: "~> v2" diff --git a/.github/workflows/testdata.yaml b/.github/workflows/testdata.yaml index e11f0f7..5854cd7 100644 --- a/.github/workflows/testdata.yaml +++ b/.github/workflows/testdata.yaml @@ -14,7 +14,7 @@ jobs: run: rm -rf /opt/hostedtoolcache - name: Checkout Repository - uses: actions/checkout@v6.0.1 + uses: actions/checkout@v6 - name: Fetch Hauler Binary run: curl -sfL https://get.hauler.dev | bash diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 1e8c1e0..599419b 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -20,7 +20,7 @@ jobs: run: rm -rf /opt/hostedtoolcache - name: Checkout - uses: actions/checkout@v6.0.1 + uses: actions/checkout@v6 with: fetch-depth: 0 @@ -30,13 +30,13 @@ jobs: git config user.email "github-actions[bot]@users.noreply.github.com" - name: Set Up Go - uses: actions/setup-go@v6.1.0 + uses: actions/setup-go@v6 with: go-version-file: go.mod check-latest: true - name: Install Go Releaser - uses: goreleaser/goreleaser-action@v6.4.0 + uses: goreleaser/goreleaser-action@v6 with: install-only: true @@ -51,13 +51,13 @@ jobs: make build-all - name: Upload Hauler Binaries - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v6 with: name: hauler-binaries path: dist/* - name: Upload Coverage Report - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v6 with: name: coverage-report path: coverage.out @@ -73,7 +73,7 @@ jobs: run: rm -rf /opt/hostedtoolcache - name: Checkout - uses: actions/checkout@v6.0.1 + uses: actions/checkout@v6 with: fetch-depth: 0 @@ -89,7 +89,7 @@ jobs: sudo apt-get install -y tree - name: Download Artifacts - uses: actions/download-artifact@v6.0.0 + uses: actions/download-artifact@v6 with: name: hauler-binaries path: dist @@ -468,7 +468,7 @@ jobs: hauler store info - name: Upload Hauler Report - uses: actions/upload-artifact@v4.6.2 + uses: actions/upload-artifact@v6 with: name: hauler-report path: hauler-report.txt diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 0859d49..a0ac032 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -15,7 +15,6 @@ release: env: - vpkg=hauler.dev/go/hauler/internal/version - - cosign_version=v2.2.3+carbide.3 builds: - dir: ./cmd/hauler/. @@ -88,4 +87,4 @@ dockers_v2: "org.opencontainers.image.name": "{{.ProjectName}}-debug" "org.opencontainers.image.revision": "{{.FullCommit}}" "org.opencontainers.image.source": "{{.GitURL}}" - "org.opencontainers.image.version": "{{.Version}}" \ No newline at end of file + "org.opencontainers.image.version": "{{.Version}}" diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000..dde27a7 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,155 @@ +# Development Guide + +This document covers how to build `hauler` locally and how the project's branching strategy works. + +It's intended for contributors making code changes or maintainers managing releases. + +--- + +## Local Build + +### Prerequisites + +- **Git** - version control of the repository +- **Go** — check `go.mod` for the minimum required version +- **Make** - optional... for common commands used for builds +- **Docker** - optional... for container image builds + +### Clone the Repository + +```bash +git clone https://github.com/hauler-dev/hauler.git +cd hauler +``` + +### Build the Binary + +Using `make`... + +```bash +# run this command from the project root +make build + +# the compiled binary will be output to a directory structure and you can run it directly... +./dist/hauler_linux_amd64_v1/hauler +./dist/hauler_linux_arm64_v8.0/hauler +./dist/hauler_darwin_amd64_v1/hauler +./dist/hauler_darwin_arm64_v8.0/hauler +./dist/hauler_windows_amd64_v1/hauler.exe +./dist/hauler_windows_arm64_v8.0/hauler.exe +``` + +Using `go`... + +```bash +# run this command from the project root +go build -o hauler ./cmd/hauler + +# the compiled binary will be output to the project root and you can run it directly... +./hauler version +``` + +### Run Tests + +Using `make`... + +```bash +make test +``` + +Using `go`... + +```bash +go test ./... +``` + +### Useful Tips + +- The `--store` flag defaults to `./store` in the current working directory during local testing, so running `./hauler store add ...` from the project root is safe and self-contained. Use `rm -rf store` in the working directory to clear. +- Set `--log-level debug` when developing to get verbose output. + +--- + +## Branching Strategy + +Hauler uses a **main-first, release branch** model. All development flows through `main` and `release/x.x` branches are maintained for each minor version to support patching older release lines in parallel. + +### Branch Structure + +``` +main ← source of truth, all development targets here +release/1.3 ← 1.3.x patch line +release/1.4 ← 1.4.x patch line +``` + +Release tags (`v1.4.1`, `v1.3.2`, etc.) are always cut from the corresponding `release/X.Y` branch, never directly from `main`. + +### Where to Target Your Changes + +All pull requests should target `main` by default and maintainers are responsible for cherry picking fixes onto release branches as part of the patch release process. + +| Change Type | Target branch | +| :---------: | :-----------: | +| New features | `main` | +| Bug fixes | `main` | +| Security patches | `main` (expedited backport to affected branches) | +| Release-specific fix (see below) | `release/X.Y` directly | + +### Creating a New Release Branch + +When `main` is ready to ship a new minor version, a release branch is cut: + +```bash +git checkout main +git pull origin main +git checkout -b release/1.4 +git push origin release/1.4 +``` + +The first release is then tagged from that branch: + +```bash +git tag v1.4.0 +git push origin v1.4.0 +``` + +Development on `main` immediately continues toward the next minor. + +### Backporting a Fix to a Release Branch + +When a bug fix merged to `main` also needs to apply to an active release line, cherry-pick the commit onto the release branch and open a PR targeting it: + +```bash +git checkout release/1.3 +git pull origin release/1.3 +git checkout -b backport/fix-description-to-1.3 +git cherry-pick +git push origin backport/fix-description-to-1.3 +``` + +Open a PR targeting `release/1.3` and reference the original PR in the description. If the cherry-pick doesn't apply cleanly, resolve conflicts and note them in the PR. + +### Fixes That Only Apply to an Older Release Line + +Sometimes a bug exists in an older release but the relevant code has been removed or significantly changed in `main` — making a forward-port unnecessary or nonsensical. In these cases, it's acceptable to open a PR directly against the affected `release/X.Y` branch. + +When doing this, the PR description must explain: + +- Which versions are affected +- Why the fix does not apply to `main` or newer release lines (e.g., "this code path was removed in 1.4 when X was refactored") + +This keeps the history auditable and prevents future contributors from wondering why the fix never made it forward. + +### Summary + +``` + ┌─────────────────────────────────────────► main (next minor) + │ + │ cherry-pick / backport PRs + │ ─────────────────────────► release/1.4 (v1.4.0, v1.4.1 ...) + │ + │ ─────────────────────────► release/1.3 (v1.3.0, v1.3.1 ...) + │ + │ direct fix (older-only bug) + │ ─────────────────────────► release/1.2 (critical fixes only) +``` diff --git a/README.md b/README.md index 23dc051..4647473 100644 --- a/README.md +++ b/README.md @@ -19,23 +19,29 @@ For more information, please review the **[Hauler Documentation](https://hauler. - `!!! WARNING !!! [--products] will be updating its default registry in a future release...` - `!!! WARNING !!! [--product-registry] will be updating its default registry in a future release...` -### In Hauler v1.2.0... +### From older releases... - Upgraded the `apiVersion` to `v1` from `v1alpha1` - Users are able to use `v1` and `v1alpha1`, but `v1alpha1` is now deprecated and will be removed in a future release. We will update the community when we fully deprecate and remove the functionality of `v1alpha1` - Users will see logging notices when using the old `apiVersion` such as... - `!!! DEPRECATION WARNING !!! apiVersion [v1alpha1] will be removed in a future release...` + --- + - Updated the behavior of `hauler store load` to default to loading a `haul` with the name of `haul.tar.zst` and requires the flag of `--filename/-f` to load a `haul` with a different name - Users can load multiple `hauls` by specifying multiple flags of `--filename/-f` - updated command usage: `hauler store load --filename hauling-hauls.tar.zst` - previous command usage (do not use): `hauler store load hauling-hauls.tar.zst` + --- + - Updated the behavior of `hauler store sync` to default to syncing a `manifest` with the name of `hauler-manifest.yaml` and requires the flag of `--filename/-f` to sync a `manifest` with a different name - Users can sync multiple `manifests` by specifying multiple flags of `--filename/-f` - updated command usage: `hauler store sync --filename hauling-hauls-manifest.yaml` - previous command usage (do not use): `hauler store sync --files hauling-hauls-manifest.yaml` + --- + Please review the documentation for any additional [Known Limits, Issues, and Notices](https://docs.hauler.dev/docs/known-limits)! ## Installation diff --git a/cmd/hauler/cli/store/add.go b/cmd/hauler/cli/store/add.go index f5432c5..97ec6c9 100644 --- a/cmd/hauler/cli/store/add.go +++ b/cmd/hauler/cli/store/add.go @@ -521,7 +521,7 @@ func storeChart(ctx context.Context, s *store.Layout, cfg v1.Chart, opts *flags. var depCfg v1.Chart var err error - if strings.HasPrefix(dep.Repository, "file://") { + if strings.HasPrefix(dep.Repository, "file://") || dep.Repository == "" { subchartPath := filepath.Join(chartPath, "charts", dep.Name) depCfg = v1.Chart{Name: subchartPath, RepoURL: "", Version: ""} diff --git a/go.mod b/go.mod index ccb5e4a..a9da2ac 100644 --- a/go.mod +++ b/go.mod @@ -316,10 +316,10 @@ require ( go.mongodb.org/mongo-driver v1.17.6 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect - go.opentelemetry.io/otel v1.39.0 // indirect - go.opentelemetry.io/otel/metric v1.39.0 // indirect - go.opentelemetry.io/otel/sdk v1.39.0 // indirect - go.opentelemetry.io/otel/trace v1.39.0 // indirect + go.opentelemetry.io/otel v1.40.0 // indirect + go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/otel/sdk v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.40.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect @@ -329,7 +329,7 @@ require ( golang.org/x/mod v0.31.0 // indirect golang.org/x/net v0.48.0 // indirect golang.org/x/oauth2 v0.34.0 // indirect - golang.org/x/sys v0.39.0 // indirect + golang.org/x/sys v0.40.0 // indirect golang.org/x/term v0.38.0 // indirect golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect diff --git a/go.sum b/go.sum index 521b434..0d845ff 100644 --- a/go.sum +++ b/go.sum @@ -1027,22 +1027,22 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= -go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= -go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= +go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= -go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= -go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= -go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= -go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= -go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= -go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= -go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= -go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= +go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= +go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= +go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= +go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= +go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= +go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.step.sm/crypto v0.75.0 h1:UAHYD6q6ggYyzLlIKHv1MCUVjZIesXRZpGTlRC/HSHw= @@ -1203,8 +1203,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= -golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= diff --git a/testdata/chart-with-file-dependency-chart-1.0.0.tgz b/testdata/chart-with-file-dependency-chart-1.0.0.tgz index 30d96ee..76f8107 100644 Binary files a/testdata/chart-with-file-dependency-chart-1.0.0.tgz and b/testdata/chart-with-file-dependency-chart-1.0.0.tgz differ