mirror of
https://github.com/docker/compose.git
synced 2026-02-14 20:49:24 +08:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
083f676214 | ||
|
|
e81de103db | ||
|
|
fa39503469 | ||
|
|
a351585024 | ||
|
|
b6db1380ec | ||
|
|
2ebb475433 |
51
.github/workflows/ci.yml
vendored
51
.github/workflows/ci.yml
vendored
@@ -76,9 +76,6 @@ jobs:
|
||||
run: |
|
||||
platform=${{ matrix.platform }}
|
||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
@@ -87,7 +84,7 @@ jobs:
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Build
|
||||
uses: docker/bake-action@v5
|
||||
uses: docker/bake-action@v6
|
||||
with:
|
||||
targets: release
|
||||
set: |
|
||||
@@ -105,15 +102,12 @@ jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Test
|
||||
uses: docker/bake-action@v5
|
||||
uses: docker/bake-action@v6
|
||||
with:
|
||||
targets: test
|
||||
set: |
|
||||
@@ -149,9 +143,10 @@ jobs:
|
||||
mode=${{ matrix.mode }}
|
||||
engine=${{ matrix.engine }}
|
||||
echo "MODE_ENGINE_PAIR=${mode}-${engine}" >> $GITHUB_ENV
|
||||
-
|
||||
name: Checkout
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Docker ${{ matrix.engine }}
|
||||
run: |
|
||||
sudo systemctl stop docker.service
|
||||
@@ -159,22 +154,24 @@ jobs:
|
||||
sudo apt-get install curl
|
||||
curl -fsSL https://test.docker.com -o get-docker.sh
|
||||
sudo sh ./get-docker.sh --version ${{ matrix.engine }}
|
||||
|
||||
- name: Check Docker Version
|
||||
run: docker --version
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Set up Go
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
check-latest: true
|
||||
cache: true
|
||||
-
|
||||
name: Build
|
||||
uses: docker/bake-action@v5
|
||||
|
||||
- name: Build
|
||||
uses: docker/bake-action@v6
|
||||
with:
|
||||
source: .
|
||||
targets: binary-with-coverage
|
||||
set: |
|
||||
*.cache-from=type=gha,scope=binary-linux-amd64
|
||||
@@ -182,37 +179,37 @@ jobs:
|
||||
*.cache-to=type=gha,scope=binary-e2e-${{ matrix.mode }},mode=max
|
||||
env:
|
||||
BUILD_TAGS: e2e
|
||||
-
|
||||
name: Setup tmate session
|
||||
|
||||
- name: Setup tmate session
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
|
||||
uses: mxschmitt/action-tmate@8b4e4ac71822ed7e0ad5fb3d1c33483e9e8fb270 # v3.11
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Test plugin mode
|
||||
|
||||
- name: Test plugin mode
|
||||
if: ${{ matrix.mode == 'plugin' }}
|
||||
run: |
|
||||
rm -rf ./bin/coverage/e2e
|
||||
mkdir -p ./bin/coverage/e2e
|
||||
make e2e-compose GOCOVERDIR=bin/coverage/e2e TEST_FLAGS="-v"
|
||||
-
|
||||
name: Gather coverage data
|
||||
|
||||
- name: Gather coverage data
|
||||
if: ${{ matrix.mode == 'plugin' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-data-e2e-${{ env.MODE_ENGINE_PAIR }}
|
||||
path: bin/coverage/e2e/
|
||||
if-no-files-found: error
|
||||
-
|
||||
name: Test standalone mode
|
||||
|
||||
- name: Test standalone mode
|
||||
if: ${{ matrix.mode == 'standalone' }}
|
||||
run: |
|
||||
rm -f /usr/local/bin/docker-compose
|
||||
cp bin/build/docker-compose /usr/local/bin
|
||||
make e2e-compose-standalone
|
||||
-
|
||||
name: e2e Test Summary
|
||||
|
||||
- name: e2e Test Summary
|
||||
uses: test-summary/action@v2
|
||||
with:
|
||||
paths: /tmp/report/report.xml
|
||||
|
||||
21
.github/workflows/merge.yml
vendored
21
.github/workflows/merge.yml
vendored
@@ -80,8 +80,12 @@ jobs:
|
||||
digest: ${{ fromJSON(steps.bake.outputs.metadata).image-cross['containerimage.digest'] }}
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
name: Login to DockerHub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERPUBLICBOT_USERNAME }}
|
||||
password: ${{ secrets.DOCKERPUBLICBOT_WRITE_PAT }}
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
@@ -99,13 +103,6 @@ jobs:
|
||||
type=ref,event=tag
|
||||
type=edge
|
||||
bake-target: meta-helper
|
||||
-
|
||||
name: Login to DockerHub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERPUBLICBOT_USERNAME }}
|
||||
password: ${{ secrets.DOCKERPUBLICBOT_WRITE_PAT }}
|
||||
-
|
||||
name: Build and push image
|
||||
uses: docker/bake-action@v5
|
||||
@@ -113,14 +110,14 @@ jobs:
|
||||
with:
|
||||
files: |
|
||||
./docker-bake.hcl
|
||||
${{ steps.meta.outputs.bake-file }}
|
||||
cwd://${{ steps.meta.outputs.bake-file }}
|
||||
targets: image-cross
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
sbom: true
|
||||
provenance: mode=max
|
||||
set: |
|
||||
*.cache-from=type=gha,scope=bin-image
|
||||
*.cache-to=type=gha,scope=bin-image,mode=max
|
||||
*.attest=type=sbom
|
||||
*.attest=type=provenance,mode=max,builder-id=https://github.com/${{ env.GITHUB_REPOSITORY }}/actions/runs/${{ env.GITHUB_RUN_ID }}
|
||||
|
||||
desktop-edge-test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -150,12 +150,13 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
cw := progress.ContextWriter(ctx)
|
||||
err = InDependencyOrder(ctx, project, func(ctx context.Context, name string) error {
|
||||
service, ok := serviceToBuild[name]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
cw := progress.ContextWriter(ctx)
|
||||
serviceName := fmt.Sprintf("Service %s", name)
|
||||
|
||||
if !buildkitEnabled {
|
||||
@@ -182,12 +183,10 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
||||
return err
|
||||
}
|
||||
|
||||
cw.Event(progress.BuildingEvent(serviceName))
|
||||
digest, err := s.doBuildBuildkit(ctx, name, buildOptions, w, nodes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cw.Event(progress.BuiltEvent(serviceName))
|
||||
builtDigests[getServiceIndex(name)] = digest
|
||||
|
||||
return nil
|
||||
@@ -211,6 +210,7 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
||||
service := project.Services[names[i]]
|
||||
imageRef := api.GetImageNameOrDefault(service, project.Name)
|
||||
imageIDs[imageRef] = imageDigest
|
||||
cw.Event(progress.BuiltEvent(names[i]))
|
||||
}
|
||||
}
|
||||
return imageIDs, err
|
||||
|
||||
@@ -114,6 +114,15 @@ func (s *composeService) getSpecifiedContainer(ctx context.Context, projectName
|
||||
// containerPredicate define a predicate we want container to satisfy for filtering operations
|
||||
type containerPredicate func(c moby.Container) bool
|
||||
|
||||
func matches(c moby.Container, predicates ...containerPredicate) bool {
|
||||
for _, predicate := range predicates {
|
||||
if !predicate(c) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isService(services ...string) containerPredicate {
|
||||
return func(c moby.Container) bool {
|
||||
service := c.Labels[api.ServiceLabel]
|
||||
@@ -148,10 +157,10 @@ func isNotOneOff(c moby.Container) bool {
|
||||
}
|
||||
|
||||
// filter return Containers with elements to match predicate
|
||||
func (containers Containers) filter(predicate containerPredicate) Containers {
|
||||
func (containers Containers) filter(predicates ...containerPredicate) Containers {
|
||||
var filtered Containers
|
||||
for _, c := range containers {
|
||||
if predicate(c) {
|
||||
if matches(c, predicates...) {
|
||||
filtered = append(filtered, c)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,7 +460,7 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
|
||||
continue
|
||||
}
|
||||
|
||||
waitingFor := containers.filter(isService(dep))
|
||||
waitingFor := containers.filter(isService(dep), isNotOneOff)
|
||||
w.Events(containerEvents(waitingFor, progress.Waiting))
|
||||
if len(waitingFor) == 0 {
|
||||
if config.Required {
|
||||
|
||||
@@ -416,7 +416,7 @@ func (s *composeService) prepareContainerMACAddress(ctx context.Context, service
|
||||
return "", fmt.Errorf("a MAC address is specified for multiple networks (%s), but this feature requires Docker Engine 1.44 or later (currently: %s)", strings.Join(withMacAddress, ", "), version)
|
||||
}
|
||||
|
||||
if mainNw != nil {
|
||||
if mainNw != nil && mainNw.MacAddress != "" {
|
||||
macAddress = mainNw.MacAddress
|
||||
}
|
||||
}
|
||||
@@ -424,11 +424,11 @@ func (s *composeService) prepareContainerMACAddress(ctx context.Context, service
|
||||
return macAddress, nil
|
||||
}
|
||||
|
||||
func getAliases(project *types.Project, service types.ServiceConfig, serviceIndex int, networkKey string, useNetworkAliases bool) []string {
|
||||
func getAliases(project *types.Project, service types.ServiceConfig, serviceIndex int, cfg *types.ServiceNetworkConfig, useNetworkAliases bool) []string {
|
||||
aliases := []string{getContainerName(project.Name, service, serviceIndex)}
|
||||
if useNetworkAliases {
|
||||
aliases = append(aliases, service.Name)
|
||||
if cfg := service.Networks[networkKey]; cfg != nil {
|
||||
if cfg != nil {
|
||||
aliases = append(aliases, cfg.Aliases...)
|
||||
}
|
||||
}
|
||||
@@ -456,7 +456,7 @@ func createEndpointSettings(p *types.Project, service types.ServiceConfig, servi
|
||||
driverOpts = config.DriverOpts
|
||||
}
|
||||
return &network.EndpointSettings{
|
||||
Aliases: getAliases(p, service, serviceIndex, networkKey, useNetworkAliases),
|
||||
Aliases: getAliases(p, service, serviceIndex, config, useNetworkAliases),
|
||||
Links: links,
|
||||
IPAddress: ipv4Address,
|
||||
IPv6Gateway: ipv6Address,
|
||||
|
||||
@@ -94,12 +94,12 @@ func (s *composeService) getImageSummaries(ctx context.Context, repoTags []strin
|
||||
tag := ""
|
||||
repository := ""
|
||||
ref, err := reference.ParseDockerRef(repoTag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
repository = reference.FamiliarName(ref)
|
||||
if tagged, ok := ref.(reference.Tagged); ok {
|
||||
tag = tagged.Tag()
|
||||
if err == nil {
|
||||
// ParseDockerRef will reject a local image ID
|
||||
repository = reference.FamiliarName(ref)
|
||||
if tagged, ok := ref.(reference.Tagged); ok {
|
||||
tag = tagged.Tag()
|
||||
}
|
||||
}
|
||||
l.Lock()
|
||||
summary[repoTag] = api.ImageSummary{
|
||||
|
||||
3
pkg/e2e/fixtures/simple-composefile/id.yaml
Normal file
3
pkg/e2e/fixtures/simple-composefile/id.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
services:
|
||||
test:
|
||||
image: ${ID:?ID variable must be set}
|
||||
@@ -191,3 +191,18 @@ func TestUpProfile(t *testing.T) {
|
||||
assert.Assert(t, strings.Contains(res.Combined(), `Container foo_c Created`), res.Combined())
|
||||
assert.Assert(t, !strings.Contains(res.Combined(), `Container bar_c Created`), res.Combined())
|
||||
}
|
||||
|
||||
func TestUpImageID(t *testing.T) {
|
||||
c := NewCLI(t)
|
||||
const projectName = "compose-e2e-up-image-id"
|
||||
|
||||
digest := strings.TrimSpace(c.RunDockerCmd(t, "image", "inspect", "alpine", "-f", "{{ .ID }}").Stdout())
|
||||
_, id, _ := strings.Cut(digest, ":")
|
||||
|
||||
t.Cleanup(func() {
|
||||
c.RunDockerComposeCmd(t, "--project-name", projectName, "down", "-v")
|
||||
})
|
||||
|
||||
c = NewCLI(t, WithEnv(fmt.Sprintf("ID=%s", id)))
|
||||
c.RunDockerComposeCmd(t, "-f", "./fixtures/simple-composefile/id.yaml", "--project-name", projectName, "up")
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ func (w *ttyWriter) print() { //nolint:gocyclo
|
||||
_, _ = fmt.Fprint(w.out, aec.Show)
|
||||
}()
|
||||
|
||||
firstLine := fmt.Sprintf("[+] %s %d/%d", w.progressTitle, numDone(w.events), w.numLines)
|
||||
firstLine := fmt.Sprintf("[+] %s %d/%d", w.progressTitle, numDone(w.events), len(w.events))
|
||||
if w.numLines != 0 && numDone(w.events) == w.numLines {
|
||||
firstLine = DoneColor(firstLine)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user