Skip to content

Commit fe1b9e7

Browse files
committed
Merge branch 'main' into dockerCLI
* main: feat(wait): add human-readable String() methods to all wait strategies (docker#119) feat(image): display formatted pull progress on Windows terminals (docker#118) chore(release): add Go proxy refresh automation (docker#117) chore(release): bump module versions chore(release): prevent for pushing to personal forks (docker#115) chore(release): add pre-release checks to make the release process more consistent (docker#114) chore(volume): return pointer in FindByID (docker#105) fix(container): proper error message on empty container names (docker#113) fix(container): add to nil modifiers (docker#112) feat(container): add new functional options to add container config, hostConfig and endpointSettings (docker#111) feat(container): configure pull handler at container creation (docker#110)
2 parents f6c2fad + c1a5f75 commit fe1b9e7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+794
-56
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/bin/bash
2+
3+
# =============================================================================
4+
# Pre-Release Check Script
5+
# =============================================================================
6+
# Description: Verifies that pre-release was completed successfully for a module
7+
# by checking if the next-tag file exists and matches version.go
8+
#
9+
# Usage: ./.github/scripts/check-pre-release.sh <module>
10+
#
11+
# Arguments:
12+
# module - Name of the module to check (required)
13+
# Examples: client, container, config, context, image, network
14+
#
15+
# Exit Codes:
16+
# 0 - Check passed
17+
# 1 - Check failed (missing files or version mismatch)
18+
#
19+
# Examples:
20+
# ./.github/scripts/check-pre-release.sh client
21+
# ./.github/scripts/check-pre-release.sh container
22+
#
23+
# Dependencies:
24+
# - grep (for parsing version.go)
25+
#
26+
# Files Checked:
27+
# - .github/scripts/.build/<module>-next-tag - Pre-release version file
28+
# - <module>/version.go - Current version file
29+
#
30+
# =============================================================================
31+
32+
set -e
33+
34+
# Source common functions
35+
readonly SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
36+
source "${SCRIPT_DIR}/common.sh"
37+
38+
# Get module name from argument and lowercase it
39+
readonly MODULE=$(echo "${1:-}" | tr '[:upper:]' '[:lower:]')
40+
41+
if [[ -z "$MODULE" ]]; then
42+
echo "Error: Module name is required"
43+
echo "Usage: $0 <module>"
44+
echo "Example: $0 client"
45+
exit 1
46+
fi
47+
48+
echo "Checking if pre-release was completed for module: ${MODULE}"
49+
50+
# Check if next-tag file exists
51+
readonly BUILD_FILE="${BUILD_DIR}/${MODULE}-next-tag"
52+
if [[ ! -f "${BUILD_FILE}" ]]; then
53+
echo "Error: Missing build file for module '${MODULE}' at ${BUILD_FILE}"
54+
echo "Please run 'make pre-release-all' or 'make pre-release' first (with DRY_RUN=false)"
55+
exit 1
56+
fi
57+
58+
# Read next version from build file
59+
readonly NEXT_VERSION=$(cat "${BUILD_FILE}" | tr -d '\n')
60+
readonly NEXT_VERSION_NO_V="${NEXT_VERSION#v}"
61+
62+
# Check if version.go exists
63+
readonly VERSION_FILE="${ROOT_DIR}/${MODULE}/version.go"
64+
if [[ ! -f "${VERSION_FILE}" ]]; then
65+
echo "Error: version.go not found at ${VERSION_FILE}"
66+
exit 1
67+
fi
68+
69+
# Read current version from version.go
70+
readonly CURRENT_VERSION=$(get_version_from_file "${VERSION_FILE}")
71+
72+
# Compare versions
73+
if [[ "${CURRENT_VERSION}" != "${NEXT_VERSION_NO_V}" ]]; then
74+
echo "Error: Version mismatch for module '${MODULE}'"
75+
echo " Expected (from ${BUILD_FILE}): ${NEXT_VERSION_NO_V}"
76+
echo " Actual (from ${VERSION_FILE}): ${CURRENT_VERSION}"
77+
echo "Please run 'make pre-release-all' or 'make pre-release' again (with DRY_RUN=false)"
78+
exit 1
79+
fi
80+
81+
echo "✅ Pre-release check passed for module: ${MODULE} (version: ${NEXT_VERSION_NO_V})"
82+
exit 0

.github/scripts/common.sh

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ readonly CURRENT_DIR="$(get_script_dir)"
3939
readonly ROOT_DIR="$(dirname $(dirname "${CURRENT_DIR}"))"
4040
readonly BUILD_DIR="${ROOT_DIR}/.github/scripts/.build"
4141
readonly GITHUB_REPO="github.com/docker/go-sdk"
42+
readonly EXPECTED_ORIGIN_SSH="[email protected]:docker/go-sdk.git"
43+
readonly EXPECTED_ORIGIN_HTTPS="https://${GITHUB_REPO}.git"
4244
readonly DRY_RUN="${DRY_RUN:-true}"
4345

4446
# This function is used to trigger the Go proxy to fetch the module.
@@ -67,6 +69,34 @@ execute_or_echo() {
6769
fi
6870
}
6971

72+
# Validate that git remote origin points to the correct repository
73+
# This prevents accidentally pushing to the wrong remote
74+
validate_git_remote() {
75+
local actual_origin="$(git -C "${ROOT_DIR}" remote get-url origin 2>/dev/null || echo "")"
76+
77+
if [[ -z "$actual_origin" ]]; then
78+
echo "❌ Error: No 'origin' remote found"
79+
echo "Please configure the origin remote first:"
80+
echo " git remote add origin ${EXPECTED_ORIGIN_SSH}"
81+
exit 1
82+
fi
83+
84+
# Accept both SSH and HTTPS formats for the docker/go-sdk repository
85+
if [[ "$actual_origin" != "$EXPECTED_ORIGIN_SSH" ]] && \
86+
[[ "$actual_origin" != "$EXPECTED_ORIGIN_HTTPS" ]]; then
87+
echo "❌ Error: Git remote 'origin' points to the wrong repository"
88+
echo " Expected: ${EXPECTED_ORIGIN_SSH}"
89+
echo " (or ${EXPECTED_ORIGIN_HTTPS})"
90+
echo " Actual: ${actual_origin}"
91+
echo ""
92+
echo "To fix this, update your origin remote:"
93+
echo " git remote set-url origin ${EXPECTED_ORIGIN_SSH}"
94+
exit 1
95+
fi
96+
97+
echo "✅ Git remote validation passed: origin → ${actual_origin}"
98+
}
99+
70100
# Function to get modules from go.work
71101
get_modules() {
72102
go work edit -json | jq -r '.Use[] | "\(.DiskPath | ltrimstr("./"))"' | tr '\n' ' ' && echo
@@ -85,11 +115,20 @@ get_next_tag() {
85115
echo "${next_tag_path}"
86116
}
87117

118+
# Extract version string from a version.go file
119+
# Usage: get_version_from_file <path_to_version.go>
120+
# Returns: version string (e.g., "0.1.0-alpha011")
121+
get_version_from_file() {
122+
local file="$1"
123+
# Use pattern that allows arbitrary whitespace around = sign
124+
grep -o 'version[[:space:]]*=[[:space:]]*"[^"]*"' "$file" | cut -d'"' -f2
125+
}
126+
88127
# Portable in-place sed editing that works on both BSD (macOS) and GNU (Linux) sed
89128
portable_sed() {
90129
local pattern="$1"
91130
local file="$2"
92-
131+
93132
# Detect sed version and use appropriate syntax
94133
if sed --version >/dev/null 2>&1; then
95134
# GNU sed (Linux)

.github/scripts/refresh-proxy.sh

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/bin/bash
2+
3+
# =============================================================================
4+
# Go Proxy Refresh Script
5+
# =============================================================================
6+
# Description: Triggers the Go proxy to refresh/fetch a module version
7+
# This is useful to ensure pkg.go.dev has the latest version
8+
#
9+
# Usage: ./.github/scripts/refresh-proxy.sh <module>
10+
#
11+
# Arguments:
12+
# module - Name of the module to refresh (required)
13+
# Examples: client, container, config, context, image, network
14+
#
15+
# Examples:
16+
# ./.github/scripts/refresh-proxy.sh client
17+
# ./.github/scripts/refresh-proxy.sh container
18+
#
19+
# Dependencies:
20+
# - git (for finding latest tag)
21+
# - curl (for triggering Go proxy)
22+
#
23+
# =============================================================================
24+
25+
set -e
26+
27+
# Source common functions
28+
readonly SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
29+
source "${SCRIPT_DIR}/common.sh"
30+
31+
# Get module name from argument and lowercase it
32+
readonly MODULE=$(echo "${1:-}" | tr '[:upper:]' '[:lower:]')
33+
34+
if [[ -z "$MODULE" ]]; then
35+
echo "Error: Module name is required"
36+
echo "Usage: $0 <module>"
37+
echo "Example: $0 client"
38+
exit 1
39+
fi
40+
41+
echo "Refreshing Go proxy for module: ${MODULE}"
42+
43+
# Check if version.go exists
44+
readonly VERSION_FILE="${ROOT_DIR}/${MODULE}/version.go"
45+
if [[ ! -f "${VERSION_FILE}" ]]; then
46+
echo "Error: version.go not found at ${VERSION_FILE}"
47+
exit 1
48+
fi
49+
50+
# Read version from version.go
51+
VERSION=$(get_version_from_file "${VERSION_FILE}")
52+
53+
if [[ -z "$VERSION" ]]; then
54+
echo "Error: Could not extract version from ${VERSION_FILE}"
55+
exit 1
56+
fi
57+
58+
# Ensure version has v prefix for the tag
59+
if [[ ! "${VERSION}" =~ ^v ]]; then
60+
VERSION="v${VERSION}"
61+
fi
62+
63+
echo "Current version: ${VERSION}"
64+
echo "Triggering Go proxy refresh..."
65+
66+
# Trigger Go proxy (bypass dry-run since this is a read-only operation)
67+
DRY_RUN=false curlGolangProxy "${MODULE}" "${VERSION}"
68+
69+
echo "✅ Go proxy refresh completed for ${MODULE}@${VERSION}"
70+
echo "The module should be available at: https://pkg.go.dev/${GITHUB_REPO}/${MODULE}@${VERSION}"

.github/scripts/release.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ set -e
4747
readonly SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4848
source "${SCRIPT_DIR}/common.sh"
4949

50+
# Validate git remote before doing anything
51+
validate_git_remote
52+
5053
MODULE="${1:-}"
5154

5255
# Collect and stage changes across modules, then create a single commit

Makefile

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,17 @@ clean-build-dir:
2424
@rm -rf .github/scripts/.build
2525
@mkdir -p .github/scripts/.build
2626

27-
# Release version for all modules
28-
release-all: clean-build-dir
27+
# Pre-release version for all modules
28+
pre-release-all: clean-build-dir
2929
@echo "Preparing releasing versions for all modules..."
3030
$(call for-all-modules,make pre-release)
3131

32+
# Release version for all modules. It must be run after pre-release-all.
33+
release-all:
34+
$(call for-all-modules,make check-pre-release)
3235
@./.github/scripts/release.sh
36+
37+
# Refresh Go proxy for all modules
38+
refresh-proxy-all:
39+
@echo "Refreshing Go proxy for all modules..."
40+
$(call for-all-modules,make refresh-proxy)

RELEASING.md

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Each module's version is defined in the `version.go` file at the root of the mod
1414

1515
The primary way to perform releases is through GitHub Actions workflows.
1616

17+
**Important**: GitHub Actions release workflows can only be run from the `main` branch. The workflows will automatically be skipped if triggered from any other branch. This is a safety measure to ensure releases are only performed from the primary branch.
18+
1719
#### Releasing All Modules
1820

1921
1. Go to the [Actions tab](../../actions) in the GitHub repository
@@ -43,6 +45,8 @@ The primary way to perform releases is through GitHub Actions workflows.
4345

4446
If you need to perform releases manually or troubleshoot issues:
4547

48+
**Note**: Manual releases using `make` commands can technically be run from any branch, but should be run from the `main` branch for consistency with the GitHub Actions workflows.
49+
4650
#### Prerequisites
4751
- Docker installed (for semver-tool)
4852
- jq installed (`brew install jq` on macOS)
@@ -51,16 +55,21 @@ If you need to perform releases manually or troubleshoot issues:
5155

5256
#### Releasing All Modules
5357
```bash
54-
# Dry run to preview changes (no git changes made)
55-
DRY_RUN=true make release-all
58+
# Step 1: Dry run to preview version changes (no build files created)
59+
DRY_RUN=true make pre-release-all # Explicit dry run, safe to run
60+
61+
# Step 2: Prepare release for real (creates build files in .github/scripts/.build/)
62+
DRY_RUN=false make pre-release-all
5663

57-
# Actual release (creates commits, tags, and pushes)
64+
# Step 3: Actual release (automatically checks pre-release, creates commits, tags, and pushes)
5865
DRY_RUN=false make release-all
5966

6067
# With specific bump type
6168
BUMP_TYPE=patch DRY_RUN=false make release-all
6269
```
6370

71+
**Note**: The `release-all` target automatically runs `check-pre-release` for all modules to verify that `pre-release-all` was completed successfully (with `DRY_RUN=false`). If you try to run `release-all` without first running `pre-release-all` with `DRY_RUN=false`, it will fail with an error.
72+
6473
#### Releasing a Single Module
6574
```bash
6675
# From the module directory
@@ -107,19 +116,44 @@ DRY_RUN=false ./.github/scripts/release.sh container
107116

108117
## What Happens During Release
109118

110-
### 1. Version Calculation
119+
### 1. Pre-Release Phase
120+
The `pre-release-all` or `pre-release` command must be run first:
111121
- Finds latest tag for each module
112122
- Uses semver-tool to calculate next version
113123
- Handles prerelease numbering with leading zeros
124+
- Writes the next version to a file in the build directory, located at `.github/scripts/.build/<module>-next-tag`
125+
126+
### 2. Release Validation Checks
127+
Before creating any commits or tags, the release script performs the following validation checks:
128+
129+
**Git Remote Validation:**
130+
- Verifies that the `origin` remote points to `[email protected]:docker/go-sdk.git` (or HTTPS equivalent)
131+
- Prevents accidentally pushing releases to forks or personal repositories
132+
- If validation fails, the script aborts immediately with instructions to fix the remote
133+
134+
**Pre-Release Verification:**
135+
- The `release-all` command automatically runs `check-pre-release` for all modules
136+
- Verifies the `.github/scripts/.build` directory exists
137+
- Checks each module has a corresponding `<module>-next-tag` file
138+
- Validates the version in `<module>-next-tag` matches the version in `<module>/version.go`
139+
- If any checks fail, the release is aborted with an error message
140+
- Implemented in `.github/scripts/check-pre-release.sh`
141+
- Ensures `pre-release-all` was completed successfully (with `DRY_RUN=false`)
142+
143+
You can manually run the check for a specific module:
144+
```bash
145+
make -C client check-pre-release
146+
# or
147+
cd client && make check-pre-release
148+
```
114149

115-
### 2. File Updates
150+
### 3. File Updates
116151
For each module:
117-
- Writes the next version to a file in the build directory, located at `.github/scripts/.build/<module>-next-tag`. This is a temporary file that is used to store the next version for the module.
118152
- Updates `<module>/version.go` with new version
119153
- Updates all `go.mod` files with new cross-module dependencies
120154
- Runs `go mod tidy` to update `go.sum` files
121155

122-
### 3. Git Operations
156+
### 4. Git Operations
123157
When `DRY_RUN=false`:
124158
- Creates a single commit with all version changes
125159
- Creates git tags for each module (e.g., `client/v0.1.0-alpha006`)
@@ -131,7 +165,7 @@ When `DRY_RUN=true`:
131165
- Shows diffs of version files
132166
- Completely safe to run multiple times
133167

134-
### 4. Go Proxy Registration
168+
### 5. Go Proxy Registration
135169
When `DRY_RUN=false`:
136170
- Triggers Go proxy to fetch new module versions
137171
- Makes modules immediately available for download via `go get`

client/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ require (
88
github.com/docker/cli v28.5.1+incompatible
99
github.com/docker/docker v28.3.2+incompatible
1010
github.com/docker/go-connections v0.5.0
11-
github.com/docker/go-sdk/config v0.1.0-alpha010
1211
github.com/opencontainers/image-spec v1.1.1
1312
github.com/stretchr/testify v1.11.1
1413
)
@@ -66,4 +65,5 @@ require (
6665
google.golang.org/grpc v1.75.0 // indirect
6766
google.golang.org/protobuf v1.36.8 // indirect
6867
gopkg.in/yaml.v3 v3.0.1 // indirect
68+
gotest.tools/v3 v3.5.2 // indirect
6969
)

client/go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj
4949
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
5050
github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916 h1:yWHOI+vFjEsAakUTSrtqc/SAHrhSkmn48pqjidZX3QA=
5151
github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
52-
github.com/docker/go-sdk/config v0.1.0-alpha010 h1:OkNQeadloIEbTi1qIEXbDY5PqAYQg3igkBnKffHMGXg=
53-
github.com/docker/go-sdk/config v0.1.0-alpha010/go.mod h1:2lhg2sMZMKTtBVrsTG2Hn9P0dXMp1weecaJrE7OtNDM=
5452
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
5553
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
5654
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=

client/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package client
22

33
const (
4-
version = "0.1.0-alpha010"
4+
version = "0.1.0-alpha011"
55
)
66

77
// Version returns the version of the client package.

0 commit comments

Comments
 (0)