mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
Merge pull request #51300 from rafaelcamelo31/50486_api_move_scripts
api: move scripts to generate and validate swagger to api module
This commit is contained in:
23
.github/workflows/test.yml
vendored
23
.github/workflows/test.yml
vendored
@@ -163,6 +163,29 @@ jobs:
|
||||
run: |
|
||||
make -o build validate-${{ matrix.script }}
|
||||
|
||||
validate-api-swagger:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10 # guardrails timeout for the whole job
|
||||
defaults:
|
||||
run:
|
||||
working-directory: api
|
||||
needs:
|
||||
- validate-dco
|
||||
name: validate (api-swagger)
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Build api module image
|
||||
run: |
|
||||
make build GO_VERSION=${{ env.GO_VERSION }}
|
||||
-
|
||||
name: Validate swagger
|
||||
run: |
|
||||
make validate-swagger
|
||||
make validate-swagger-gen
|
||||
|
||||
smoke-prepare:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10 # guardrails timeout for the whole job
|
||||
|
||||
17
Dockerfile
17
Dockerfile
@@ -83,22 +83,6 @@ RUN --mount=type=cache,sharing=locked,id=moby-criu-aptlib,target=/var/lib/apt \
|
||||
FROM distribution/distribution:$REGISTRY_VERSION AS registry
|
||||
RUN mkdir /build && mv /bin/registry /build/registry
|
||||
|
||||
# go-swagger
|
||||
FROM base AS swagger
|
||||
WORKDIR /go/src/github.com/go-swagger/go-swagger
|
||||
ARG TARGETPLATFORM
|
||||
# GO_SWAGGER_VERSION specifies the version of the go-swagger binary to install.
|
||||
# Go-swagger is used in CI for generating types from swagger.yaml in
|
||||
# hack/validate/swagger-gen
|
||||
ARG GO_SWAGGER_VERSION=v0.33.1
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build,id=swagger-build-$TARGETPLATFORM \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
--mount=type=tmpfs,target=/go/src/ <<EOT
|
||||
set -e
|
||||
GOBIN=/build CGO_ENABLED=0 xx-go install "github.com/go-swagger/go-swagger/cmd/swagger@${GO_SWAGGER_VERSION}"
|
||||
xx-verify /build/swagger
|
||||
EOT
|
||||
|
||||
# frozen-images
|
||||
# See also frozenImages in "testutil/environment/protect.go" (which needs to
|
||||
# be updated when adding images to this list)
|
||||
@@ -420,7 +404,6 @@ FROM docker/compose-bin:${COMPOSE_VERSION} AS compose
|
||||
|
||||
FROM base AS dev-systemd-false
|
||||
COPY --link --from=frozen-images /build/ /docker-frozen-images
|
||||
COPY --link --from=swagger /build/ /usr/local/bin/
|
||||
COPY --link --from=delve /build/ /usr/local/bin/
|
||||
COPY --link --from=gowinres /build/ /usr/local/bin/
|
||||
COPY --link --from=tini /build/ /usr/local/bin/
|
||||
|
||||
17
Makefile
17
Makefile
@@ -118,11 +118,8 @@ DELVE_PORT_FORWARD := $(if $(DELVE_PORT),-p "$(DELVE_PORT)",)
|
||||
|
||||
DOCKER_FLAGS := $(DOCKER) run --rm --privileged $(DOCKER_CONTAINER_NAME) $(DOCKER_ENVS) $(DOCKER_MOUNT) $(DOCKER_PORT_FORWARD) $(DELVE_PORT_FORWARD)
|
||||
|
||||
SWAGGER_DOCS_PORT ?= 9000
|
||||
|
||||
define \n
|
||||
|
||||
|
||||
endef
|
||||
|
||||
# if this session isn't interactive, then we don't want to allocate a
|
||||
@@ -263,20 +260,12 @@ win: bundles ## cross build the binary for windows
|
||||
$(BAKE_CMD) --set *.platform=windows/amd64 binary
|
||||
|
||||
.PHONY: swagger-gen
|
||||
swagger-gen:
|
||||
docker run --rm -v $(PWD):/go/src/github.com/docker/docker \
|
||||
-w /go/src/github.com/docker/docker \
|
||||
--entrypoint hack/generate-swagger-api.sh \
|
||||
-e GOPATH=/go \
|
||||
quay.io/goswagger/swagger:0.7.4
|
||||
swagger-gen: ## generate swagger API types
|
||||
$(MAKE) -C api swagger-gen
|
||||
|
||||
.PHONY: swagger-docs
|
||||
swagger-docs: ## preview the API documentation
|
||||
@echo "API docs preview will be running at http://localhost:$(SWAGGER_DOCS_PORT)"
|
||||
@docker run --rm -v $(PWD)/api/swagger.yaml:/usr/share/nginx/html/swagger.yaml \
|
||||
-e 'REDOC_OPTIONS=hide-hostname="true" lazy-rendering' \
|
||||
-p $(SWAGGER_DOCS_PORT):80 \
|
||||
bfirsh/redoc:1.14.0
|
||||
$(MAKE) -C api swagger-docs
|
||||
|
||||
.PHONY: generate-files
|
||||
generate-files:
|
||||
|
||||
25
api/Dockerfile
Normal file
25
api/Dockerfile
Normal file
@@ -0,0 +1,25 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG GO_VERSION=1.25.4
|
||||
|
||||
FROM golang:${GO_VERSION}-alpine AS base
|
||||
RUN apk add --no-cache bash make yamllint
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
# go-swagger
|
||||
FROM base AS swagger
|
||||
WORKDIR /go/src/github.com/go-swagger/go-swagger
|
||||
# GO_SWAGGER_VERSION specifies the version of the go-swagger binary to install.
|
||||
# Go-swagger is used in CI for generating types from swagger.yaml in
|
||||
# api/scripts/generate-swagger-api.sh
|
||||
ARG GO_SWAGGER_VERSION=v0.33.1
|
||||
ARG TARGETPLATFORM
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build,id=swagger-build-$TARGETPLATFORM \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
CGO_ENABLED=0 go install "github.com/go-swagger/go-swagger/cmd/swagger@${GO_SWAGGER_VERSION}" && \
|
||||
/go/bin/swagger version
|
||||
|
||||
# dev is a dev-environment to work with the api module.
|
||||
FROM base AS dev
|
||||
COPY --from=swagger /go/bin/swagger /usr/local/bin/swagger
|
||||
WORKDIR /go/src/github.com/moby/moby/api
|
||||
64
api/Makefile
Normal file
64
api/Makefile
Normal file
@@ -0,0 +1,64 @@
|
||||
# API Module Makefile
|
||||
# This Makefile provides targets for the swagger generation and validation
|
||||
# which are specific to the API module.
|
||||
|
||||
DOCKER ?= docker
|
||||
BUILDX ?= $(DOCKER) buildx
|
||||
|
||||
API_DIR := $(CURDIR)
|
||||
PROJECT_PATH := /go/src/github.com/moby/moby
|
||||
|
||||
DOCKER_MOUNT := -v "$(API_DIR):$(PROJECT_PATH)/api"
|
||||
|
||||
DOCKER_IMAGE := docker-api-dev
|
||||
|
||||
DOCKER_WORKDIR := -w $(PROJECT_PATH)/api
|
||||
|
||||
DOCKER_FLAGS := $(DOCKER) run --rm $(DOCKER_MOUNT) $(DOCKER_WORKDIR)
|
||||
DOCKER_RUN := $(DOCKER_FLAGS) "$(DOCKER_IMAGE)"
|
||||
|
||||
DOCKER_CONTAINER_NAME := $(if $(CONTAINER_NAME),--name $(CONTAINER_NAME),)
|
||||
|
||||
BUILD_CMD := $(BUILDX) build
|
||||
GO_VERSION ?= 1.25.4
|
||||
SWAGGER_VERSION ?= v0.33.1
|
||||
SWAGGER_DOCS_PORT ?= 9000
|
||||
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
$(BUILD_CMD) \
|
||||
--build-arg GO_VERSION=$(GO_VERSION) \
|
||||
--build-arg SWAGGER_VERSION=$(SWAGGER_VERSION) \
|
||||
--target dev \
|
||||
--load \
|
||||
-t "$(DOCKER_IMAGE)" \
|
||||
-f Dockerfile \
|
||||
.
|
||||
|
||||
.PHONY: swagger-gen
|
||||
swagger-gen: build ## generate swagger API types
|
||||
$(DOCKER_RUN) ./scripts/generate-swagger-api.sh
|
||||
|
||||
.PHONY: swagger-docs
|
||||
swagger-docs: ## preview the API documentation
|
||||
@echo "API docs preview will be running at http://localhost:$(SWAGGER_DOCS_PORT)"
|
||||
@docker run --rm \
|
||||
-v $(PWD)/:/usr/share/nginx/html/swagger/ \
|
||||
-e 'REDOC_OPTIONS=hide-hostname="true" lazy-rendering' \
|
||||
-e SPEC_URL="swagger/swagger.yaml" \
|
||||
-p $(SWAGGER_DOCS_PORT):80 \
|
||||
redocly/redoc:v2.5.1
|
||||
|
||||
.PHONY: validate-swagger
|
||||
validate-swagger: build ## validate the swagger.yaml file
|
||||
$(DOCKER_RUN) ./scripts/validate-swagger.sh
|
||||
|
||||
.PHONY: validate-swagger-gen
|
||||
validate-swagger-gen: build ## validate generated types are up-to-date
|
||||
$(DOCKER_RUN) ./scripts/validate-swagger-gen.sh
|
||||
|
||||
.PHONY: help
|
||||
help: ## display this help message
|
||||
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z0-9_-]+:.*?## / {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||
@@ -3,24 +3,26 @@
|
||||
# -*- indent-tabs-mode: t -*-
|
||||
set -eu
|
||||
|
||||
API_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
|
||||
generate_model() {
|
||||
local package="$1"
|
||||
shift
|
||||
mapfile
|
||||
swagger generate model --spec=api/swagger.yaml \
|
||||
--target=api --model-package="$package" \
|
||||
--config-file=api/swagger-gen.yaml \
|
||||
--template-dir=api/templates --allow-template-override \
|
||||
swagger generate model --spec="${API_DIR}/swagger.yaml" \
|
||||
--target="${API_DIR}" --model-package="$package" \
|
||||
--config-file="${API_DIR}/swagger-gen.yaml" \
|
||||
--template-dir="${API_DIR}/templates" --allow-template-override \
|
||||
"$@" \
|
||||
$(printf -- '--name=%s ' "${MAPFILE[@]}")
|
||||
}
|
||||
|
||||
generate_operation() {
|
||||
mapfile
|
||||
swagger generate operation --spec=api/swagger.yaml \
|
||||
--target=api --api-package=types --model-package=types \
|
||||
--config-file=api/swagger-gen.yaml \
|
||||
--template-dir=api/templates --allow-template-override \
|
||||
swagger generate operation --spec="${API_DIR}/swagger.yaml" \
|
||||
--target="${API_DIR}" --api-package=types --model-package=types \
|
||||
--config-file="${API_DIR}/swagger-gen.yaml" \
|
||||
--template-dir="${API_DIR}/templates" --allow-template-override \
|
||||
"$@" \
|
||||
$(printf -- '--name=%s ' "${MAPFILE[@]}")
|
||||
}
|
||||
52
api/scripts/validate-swagger-gen.sh
Executable file
52
api/scripts/validate-swagger-gen.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
API_DIR="${SCRIPT_DIR}/.."
|
||||
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
trap "rm -rf ${TMP_DIR}" EXIT
|
||||
GEN_FILES=()
|
||||
|
||||
echo "Validating generated code..."
|
||||
echo "Separating generated files from handwritten files..."
|
||||
while IFS= read -r file; do
|
||||
GEN_FILES+=("$file")
|
||||
done < <(grep -rl "// Code generated" "${API_DIR}/types" || true)
|
||||
|
||||
echo "Copying generated files into temporary folder..."
|
||||
for f in "${GEN_FILES[@]}"; do
|
||||
mkdir -p "${TMP_DIR}/$(dirname "${f#${API_DIR}/}")"
|
||||
cp "$f" "${TMP_DIR}/${f#${API_DIR}/}"
|
||||
done
|
||||
|
||||
cp "${API_DIR}/swagger.yaml" "${TMP_DIR}/"
|
||||
cp "${API_DIR}/swagger-gen.yaml" "${TMP_DIR}/"
|
||||
cp -r "${API_DIR}/templates" "${TMP_DIR}/" 2> /dev/null || true
|
||||
|
||||
echo "Generating swagger types in temporary folder..."
|
||||
(
|
||||
cd "${TMP_DIR}"
|
||||
"${SCRIPT_DIR}/generate-swagger-api.sh" > /dev/null 2>&1
|
||||
)
|
||||
|
||||
echo "Run diff for all generated files..."
|
||||
DIFF_FOUND=false
|
||||
for f in "${GEN_FILES[@]}"; do
|
||||
REL="${f#${API_DIR}/}"
|
||||
if ! diff -q "${TMP_DIR}/${REL}" "${API_DIR}/${REL}" > /dev/null 2>&1; then
|
||||
echo "Difference found in ${REL}"
|
||||
diff -u "${TMP_DIR}/${REL}" "${API_DIR}/${REL}" || true
|
||||
DIFF_FOUND=true
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$DIFF_FOUND" = true ]; then
|
||||
echo
|
||||
echo "Swagger validation failed. Please run:"
|
||||
echo " ./scripts/generate-swagger-api.sh"
|
||||
echo "and commit updated generated files."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Swagger file is up to date."
|
||||
16
api/scripts/validate-swagger.sh
Executable file
16
api/scripts/validate-swagger.sh
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Expected to be in api directory
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")/.."
|
||||
|
||||
echo "Validating swagger.yaml..."
|
||||
|
||||
yamllint -f parsable -c validate/yamllint.yaml swagger.yaml
|
||||
|
||||
if out=$(swagger validate swagger.yaml); then
|
||||
echo "Validation done! ${out}"
|
||||
else
|
||||
echo "${out}" >&2
|
||||
false
|
||||
fi
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
SCRIPTDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${SCRIPTDIR}/.validate"
|
||||
|
||||
IFS=$'\n'
|
||||
files=($(validate_diff --diff-filter=ACMR --name-only -- 'api/swagger.yaml' || true))
|
||||
unset IFS
|
||||
|
||||
if [ -n "${TEST_FORCE_VALIDATE:-}" ] || [ ${#files[@]} -gt 0 ]; then
|
||||
yamllint -f parsable -c "${SCRIPTDIR}"/yamllint.yaml api/swagger.yaml
|
||||
if out=$(swagger validate api/swagger.yaml); then
|
||||
echo "Congratulations! ${out}"
|
||||
else
|
||||
echo "${out}" >&2
|
||||
false
|
||||
fi
|
||||
fi
|
||||
@@ -1,29 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
SCRIPTDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${SCRIPTDIR}/.validate"
|
||||
|
||||
IFS=$'\n'
|
||||
files=($(validate_diff --diff-filter=ACMR --name-only -- 'api/types/' 'api/swagger.yaml' || true))
|
||||
unset IFS
|
||||
|
||||
if [ -n "${TEST_FORCE_VALIDATE:-}" ] || [ ${#files[@]} -gt 0 ]; then
|
||||
"${SCRIPTDIR}"/../generate-swagger-api.sh 2> /dev/null
|
||||
# Let see if the working directory is clean
|
||||
diffs="$(git diff -- api/types/)"
|
||||
if [ "$diffs" ]; then
|
||||
{
|
||||
echo 'The result of hack/generate-swagger-api.sh differs'
|
||||
echo
|
||||
echo "$diffs"
|
||||
echo
|
||||
echo 'Please update api/swagger.yaml with any API changes, then '
|
||||
echo 'run hack/generate-swagger-api.sh.'
|
||||
} >&2
|
||||
false
|
||||
else
|
||||
echo 'Congratulations! All API changes are done the right way.'
|
||||
fi
|
||||
else
|
||||
echo 'No api/types/ or api/swagger.yaml changes in diff.'
|
||||
fi
|
||||
Reference in New Issue
Block a user