From dd3f59db5a6a4f2039b5d25306407dae84f4a735 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Thu, 21 Aug 2025 19:51:25 +0200 Subject: [PATCH 1/4] chore: 0.38.0-dev --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 20606a43c..5fa695f59 100644 --- a/version.go +++ b/version.go @@ -9,7 +9,7 @@ import ( var CurrentCommit string // CurrentVersionNumber is the current application's version literal. -const CurrentVersionNumber = "0.37.0-dev" +const CurrentVersionNumber = "0.38.0-dev" const ApiVersion = "/kubo/" + CurrentVersionNumber + "/" //nolint From ae068a806181dc09d4d679ba8d3c6e5f3547afac Mon Sep 17 00:00:00 2001 From: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Date: Fri, 22 Aug 2025 13:57:35 -0700 Subject: [PATCH 2/4] fix: harness tests random panic (#10933) * fix: harness tests random panic Connecting nodes in parallel can cause TLS handshake failures. For each node, connect to the other nodes serially. It is not necessary to connect in parallel as it does not save any significant time. Closes #10932 --- test/cli/harness/nodes.go | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/test/cli/harness/nodes.go b/test/cli/harness/nodes.go index 113289e3c..8a5451e03 100644 --- a/test/cli/harness/nodes.go +++ b/test/cli/harness/nodes.go @@ -5,7 +5,6 @@ import ( . "github.com/ipfs/kubo/test/cli/testutils" "github.com/multiformats/go-multiaddr" - "golang.org/x/sync/errgroup" ) // Nodes is a collection of Kubo nodes along with operations on groups of nodes. @@ -17,37 +16,28 @@ func (n Nodes) Init(args ...string) Nodes { } func (n Nodes) ForEachPar(f func(*Node)) { - group := &errgroup.Group{} + var wg sync.WaitGroup for _, node := range n { + wg.Add(1) node := node - group.Go(func() error { + go func() { + defer wg.Done() f(node) - return nil - }) - } - err := group.Wait() - if err != nil { - panic(err) + }() } + wg.Wait() } func (n Nodes) Connect() Nodes { - wg := sync.WaitGroup{} for i, node := range n { for j, otherNode := range n { if i == j { continue } - node := node - otherNode := otherNode - wg.Add(1) - go func() { - defer wg.Done() - node.Connect(otherNode) - }() + // Do not connect in parallel, because that can cause TLS handshake problems on some platforms. + node.Connect(otherNode) } } - wg.Wait() for _, node := range n { firstPeer := node.Peers()[0] if _, err := firstPeer.ValueForProtocol(multiaddr.P_P2P); err != nil { From 15f723a15e7c79f12857f52e652ffecb6d043e4d Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Sun, 24 Aug 2025 14:30:35 +0200 Subject: [PATCH 3/4] fix: disable telemetry in test profile (#10931) * Tests: disable telemetry in tests by default Disable the plugin in cli tests and sharness by default. Enable only in telemetry tests. There are cases when tests get stuck or get killed and leave daemons hanging around. We don't want to be getting telemetry from those. * sharness: attempt to fix * sharness: add missing --bool flag * fix(ci): add omitempty to Plugin.Config field The sharness problem is that when the telemetry plugin is configured initially with 'ipfs config --bool', it creates a structure without the 'Config: null' field, but when the config is copied and replaced, it expects the structure to be preserved. Adding omitempty ensures the Config field is omitted from JSON when nil, making the config structure consistent between initial creation and replacement operations. --------- Co-authored-by: Marcin Rataj --- config/plugins.go | 2 +- test/cli/harness/node.go | 8 ++++++++ test/cli/telemetry_test.go | 5 +++++ test/sharness/lib/test-lib.sh | 8 ++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/config/plugins.go b/config/plugins.go index 08a1acb34..0c438cbd7 100644 --- a/config/plugins.go +++ b/config/plugins.go @@ -7,5 +7,5 @@ type Plugins struct { type Plugin struct { Disabled bool - Config interface{} + Config interface{} `json:",omitempty"` } diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index 6403a2f1a..0315e81df 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -245,6 +245,14 @@ func (n *Node) Init(ipfsArgs ...string) *Node { cfg.Swarm.DisableNatPortMap = true cfg.Discovery.MDNS.Enabled = n.EnableMDNS cfg.Routing.LoopbackAddressesOnLanDHT = config.True + // Telemetry disabled by default in tests. + cfg.Plugins = config.Plugins{ + Plugins: map[string]config.Plugin{ + "telemetry": config.Plugin{ + Disabled: true, + }, + }, + } }) return n } diff --git a/test/cli/telemetry_test.go b/test/cli/telemetry_test.go index 455ea7df1..69b87e80d 100644 --- a/test/cli/telemetry_test.go +++ b/test/cli/telemetry_test.go @@ -25,6 +25,7 @@ func TestTelemetry(t *testing.T) { // Create a new node node := harness.NewT(t).NewNode().Init() + node.SetIPFSConfig("Plugins.Plugins.telemetry.Disabled", false) // Set the opt-out environment variable node.Runner.Env["IPFS_TELEMETRY"] = "off" @@ -64,6 +65,7 @@ func TestTelemetry(t *testing.T) { // Create a new node node := harness.NewT(t).NewNode().Init() + node.SetIPFSConfig("Plugins.Plugins.telemetry.Disabled", false) // Set opt-out via config node.IPFS("config", "Plugins.Plugins.telemetry.Config.Mode", "off") @@ -106,6 +108,7 @@ func TestTelemetry(t *testing.T) { // Create a new node node := harness.NewT(t).NewNode().Init() + node.SetIPFSConfig("Plugins.Plugins.telemetry.Disabled", false) // Create a UUID file manually to simulate previous telemetry run uuidPath := filepath.Join(node.Dir, "telemetry_uuid") @@ -154,6 +157,7 @@ func TestTelemetry(t *testing.T) { // Create a new node node := harness.NewT(t).NewNode().Init() + node.SetIPFSConfig("Plugins.Plugins.telemetry.Disabled", false) // Capture daemon output stdout := &harness.Buffer{} @@ -255,6 +259,7 @@ func TestTelemetry(t *testing.T) { // Create a new node node := harness.NewT(t).NewNode().Init() + node.SetIPFSConfig("Plugins.Plugins.telemetry.Disabled", false) // Configure telemetry with a very short delay for testing node.IPFS("config", "Plugins.Plugins.telemetry.Config.Delay", "100ms") diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index e8030dcc4..413d0e92f 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -205,6 +205,10 @@ test_init_ipfs() { ipfs init "${args[@]}" --profile=test > /dev/null ' + test_expect_success "disable telemetry" ' + test_config_set --bool Plugins.Plugins.telemetry.Disabled "true" + ' + test_expect_success "prepare config -- mounting" ' mkdir mountdir ipfs ipns mfs && test_config_set Mounts.IPFS "$(pwd)/ipfs" && @@ -227,6 +231,10 @@ test_init_ipfs_measure() { ipfs init "${args[@]}" --profile=test,flatfs-measure > /dev/null ' + test_expect_success "disable telemetry" ' + test_config_set --bool Plugins.Plugins.telemetry.Disabled "true" + ' + test_expect_success "prepare config -- mounting" ' mkdir mountdir ipfs ipns && test_config_set Mounts.IPFS "$(pwd)/ipfs" && From 82fef0c04569701f34f769f9f8cc29f0f6ec0621 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 26 Aug 2025 17:01:06 +0200 Subject: [PATCH 4/4] feat(ci): docker linting (#10927) * feat(ci): docker linting adds hadolint to validate dockerfile best practices configures project-specific rules in .hadolint.yaml * fix(ci): enable hadolint console output adds verbose and tty format to see linting results in CI logs * test: trigger hadolint warning remove --no-install-recommends to test CI output * fix(ci): fail hadolint on warnings stricter linting to catch all best practice violations * fix: add --no-install-recommends to apt-get reduces image size by avoiding unnecessary packages * refactor: use WORKDIR instead of cd in dockerfile replaces cd commands with WORKDIR for cleaner dockerfile removes unnecessary hadolint ignore rules DL3003 and DL3009 * chore: simplify hadolint config removes unnecessary override rules for cleaner config --- .../{docker-build.yml => docker-check.yml} | 21 ++++++++++++++++--- .github/workflows/docker-image.yml | 4 ++++ .hadolint.yaml | 13 ++++++++++++ Dockerfile | 7 +++---- 4 files changed, 38 insertions(+), 7 deletions(-) rename .github/workflows/{docker-build.yml => docker-check.yml} (63%) create mode 100644 .hadolint.yaml diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-check.yml similarity index 63% rename from .github/workflows/docker-build.yml rename to .github/workflows/docker-check.yml index 24ece3fa4..e11f9830d 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-check.yml @@ -1,5 +1,7 @@ -# If we decide to run build-image.yml on every PR, we could deprecate this workflow. -name: Docker Build +# This workflow performs a quick Docker build check on PRs and pushes to master. +# It builds the Docker image and runs a basic smoke test to ensure the image works. +# This is a lightweight check - for full multi-platform builds and publishing, see docker-image.yml +name: Docker Check on: workflow_dispatch: @@ -15,7 +17,20 @@ concurrency: cancel-in-progress: true jobs: - docker-build: + lint: + if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v5 + - uses: hadolint/hadolint-action@v3.1.0 + with: + dockerfile: Dockerfile + failure-threshold: warning + verbose: true + format: tty + + build: if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest timeout-minutes: 10 diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 6d89c2980..4564c060e 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -1,3 +1,7 @@ +# This workflow builds and publishes official Docker images to Docker Hub. +# It handles multi-platform builds (amd64, arm/v7, arm64/v8) and pushes tagged releases. +# This workflow is triggered on tags, specific branches, and can be manually dispatched. +# For quick build checks during development, see docker-check.yml name: Docker Push on: diff --git a/.hadolint.yaml b/.hadolint.yaml new file mode 100644 index 000000000..78b3d23bf --- /dev/null +++ b/.hadolint.yaml @@ -0,0 +1,13 @@ +# Hadolint configuration for Kubo Docker image +# https://github.com/hadolint/hadolint + +# Ignore specific rules +ignored: + # DL3008: Pin versions in apt-get install + # We use stable base images and prefer smaller layers over version pinning + - DL3008 + +# Trust base images from these registries +trustedRegistries: + - docker.io + - gcr.io \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 0db5f33b4..6d43beefa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,9 +8,9 @@ ENV SRC_DIR=/kubo # Cache go module downloads between builds for faster rebuilds COPY go.mod go.sum $SRC_DIR/ +WORKDIR $SRC_DIR RUN --mount=type=cache,target=/go/pkg/mod \ - cd $SRC_DIR \ - && go mod download + go mod download COPY . $SRC_DIR @@ -25,8 +25,7 @@ ARG MAKE_TARGET=build # mkdir .git/objects allows git rev-parse to read commit hash for version info RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ - cd $SRC_DIR \ - && mkdir -p .git/objects \ + mkdir -p .git/objects \ && GOOS=$TARGETOS GOARCH=$TARGETARCH GOFLAGS=-buildvcs=false make ${MAKE_TARGET} IPFS_PLUGINS=$IPFS_PLUGINS # Extract required runtime tools from Debian.