This commit is contained in:
Submodule
+1
Submodule .ci/common added at 17dbcc178d
@@ -1,5 +1,6 @@
|
||||
.git
|
||||
.gitignore
|
||||
.gitmodules
|
||||
|
||||
./Makefile
|
||||
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
# CI/CD 的阶段定义,按顺序执行各阶段;默认包含`.pre`(最先执行)/`.post`(最后执行)两个阶段,不用显示定义
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- deploy
|
||||
|
||||
# 全局变量定义
|
||||
variables:
|
||||
IMG_URL: "$HARBOR_HOST/$HARBOR_PROJECT/$CI_PROJECT_NAME"
|
||||
IMG_TAG: ":latest"
|
||||
|
||||
# 默认值信息配置
|
||||
default:
|
||||
# 各 stage 使用的默认镜像,如果不定义,则为 gitlab-runner 创建时指定的镜像;各 stage 可以覆盖该值以使用不同的镜像
|
||||
image: docker.colovu.com/library/docker:20.10.16
|
||||
# Gitlab-runner 配置的执行器为 Docker 时,需要 配置对应的 dind 服务(这里使用Runner中配置的Dind服务)
|
||||
#services:
|
||||
# - name: docker.colovu.com/library/docker:20.10.16-dind
|
||||
# alias: docker
|
||||
# 流水线中,各阶段都会执行的脚本命令,包括`before_script`(在各阶段 script 前执行)/`after_script`(在各阶段 script 后执行)
|
||||
before_script:
|
||||
- |
|
||||
if [[ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]]; then
|
||||
IMG_TAG=":latest"
|
||||
else
|
||||
IMG_TAG=":$CI_COMMIT_REF_NAME"
|
||||
fi
|
||||
- docker login -u "$HARBOR_USERNAME" -p "$HARBOR_PASSWORD" $HARBOR_URL
|
||||
|
||||
# 环境变量信息
|
||||
env-variables:
|
||||
stage: .pre
|
||||
script:
|
||||
- export
|
||||
|
||||
# 编译阶段任务
|
||||
build-arm64:
|
||||
stage: build
|
||||
tags:
|
||||
- arm64
|
||||
script:
|
||||
- docker buildx build --platform=linux/arm64 --pull -t "$IMG_URL$IMG_TAG-linux-arm64" . --push
|
||||
- docker rmi "$IMG_URL$IMG_TAG-linux-arm64"
|
||||
|
||||
build-amd64:
|
||||
stage: build
|
||||
tags:
|
||||
- amd64
|
||||
script:
|
||||
- docker buildx build --platform=linux/amd64 --pull -t "$IMG_URL$IMG_TAG-linux-amd64" . --push
|
||||
- docker rmi "$IMG_URL$IMG_TAG-linux-amd64"
|
||||
|
||||
build-artifact:
|
||||
stage: build
|
||||
needs: [build-amd64, build-arm64]
|
||||
script:
|
||||
- docker manifest create "$IMG_URL$IMG_TAG" "$IMG_URL$IMG_TAG-linux-arm64" "$IMG_URL$IMG_TAG-linux-amd64"
|
||||
- docker manifest push "$IMG_URL$IMG_TAG"
|
||||
- docker manifest rm "$IMG_URL$IMG_TAG"
|
||||
|
||||
# 测试阶段任务
|
||||
test:
|
||||
stage: test
|
||||
script:
|
||||
- docker run --pull always --rm --platform=linux/arm64 "$IMG_URL$IMG_TAG" /bin/uname -a
|
||||
- docker run --pull always --rm --platform=linux/amd64 "$IMG_URL$IMG_TAG" /bin/uname -a
|
||||
- docker images -q "$IMG_URL" | sort -u | xargs docker rmi -f
|
||||
|
||||
# 部署阶段任务
|
||||
deploy:
|
||||
stage: deploy
|
||||
script:
|
||||
- echo "deploy stage"
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule ".ci/common"]
|
||||
path = .ci/common
|
||||
url = https://git.colovu.com/docker/common.git
|
||||
@@ -0,0 +1,44 @@
|
||||
# 注意:
|
||||
# 1. git commit 信息中包含"[CI SKIP]"或"[SKIP CI]"则不触发工作流(注意大小写)
|
||||
# 2. 工作步骤中包含 volumes 挂载时,需在 Woodpecker 配置中添加 volumes 挂载信任(Trust)
|
||||
# 3. lables 配置项,可配置多个;如果存在,则必须完全符合 Runner 创建时设置的 Lables 配置项
|
||||
# 4. command 中,引用自定义变量不能使用`${VAR}`方式,需要使用`$VAR`方式;带花括号的变量,会在 Woodpecker 模板引擎解析阶段被替换(此时变量为空)
|
||||
# 5. 多架构编译后推送至 SWR 报错,或单架构编译后必须在推送时明确指定架构信息才能推送;可通过在编译命令中增加参数`--provenance=false --sbom=false`解决
|
||||
# 6. 使用 Git Submodule 管理通用脚本时,需手动更新 Submodule
|
||||
|
||||
when:
|
||||
- event: push
|
||||
branch: [ "main", "master", "[0-9]*", "v[0-9]*" ]
|
||||
- event: tag
|
||||
ref: [ "refs/tags/[0-9]*", "refs/tags/v[0-9]*" ]
|
||||
|
||||
labels:
|
||||
runtime: docker
|
||||
arch: amd64
|
||||
multiarch: "true"
|
||||
|
||||
steps:
|
||||
- name: 初始化子模块
|
||||
image: alpine/git
|
||||
commands:
|
||||
- git submodule update --init --recursive
|
||||
|
||||
- name: 编译并推送镜像
|
||||
image: docker:cli
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
environment:
|
||||
SWR_REGISTRY: "swr.cn-north-4.myhuaweicloud.com"
|
||||
DOCKER_CLI_EXPERIMENTAL: enabled
|
||||
SWR_USERNAME:
|
||||
from_secret: swr_colovu_user
|
||||
SWR_PASSWORD:
|
||||
from_secret: swr_colovu_passwd
|
||||
commands:
|
||||
- |
|
||||
# 直接执行 Submodule .ci/common 下的构建推送脚本
|
||||
if [ ! -f ".ci/common/build_push.sh" ]; then
|
||||
echo "错误: 未找到 .ci/common/build_push.sh 脚本"
|
||||
exit 1
|
||||
fi
|
||||
- sh ./.ci/common/build_push.sh
|
||||
+21
-10
@@ -16,10 +16,9 @@
|
||||
# 该部分变量,在编译命令中通过 `--build-arg` 传入;如果未设置,则使用下面对应的默认值
|
||||
|
||||
ARG APP_NAME=aBuilder
|
||||
ARG APP_VER=3.20
|
||||
ARG REGISTRY_URL="swr.cn-north-4.myhuaweicloud.com/colovu/"
|
||||
ARG APT_SOURCE=ustc
|
||||
ARG LOCAL_URL="http://pkgs.colovu.com/dist"
|
||||
ARG APP_VER=3.22
|
||||
ARG REGISTRY_URL="docker.io/"
|
||||
ARG APT_SOURCE=aliyun
|
||||
|
||||
# 1. 生成镜像 =====================================================================
|
||||
FROM --platform=${TARGETPLATFORM:-linux/amd64} ${REGISTRY_URL}alpine:${APP_VER}
|
||||
@@ -29,11 +28,23 @@ ARG APP_NAME
|
||||
ARG APP_VER
|
||||
ARG APT_SOURCE
|
||||
|
||||
LABEL \
|
||||
"Version"="v${APP_VER}" \
|
||||
"Description"="Docker image for Builder based on Alpine." \
|
||||
"Github"="https://gitee.com/colovu/docker-${APP_NAME}" \
|
||||
"Vendor"="Endial Fang (endial@126.com)"
|
||||
# 镜像元数据标签 - 符合OCI镜像规范
|
||||
LABEL org.opencontainers.image.title="${APP_NAME}" \
|
||||
org.opencontainers.image.version="${APP_VER}" \
|
||||
org.opencontainers.image.description="Docker image for Alpine." \
|
||||
org.opencontainers.image.authors="Endial Fang <endial@126.com>" \
|
||||
org.opencontainers.image.url="https://gitee.com/colovu/docker-${APP_NAME}" \
|
||||
org.opencontainers.image.vendor="Endial Fang (colovu)" \
|
||||
org.opencontainers.image.licenses="Apache-2.0" \
|
||||
org.opencontainers.image.source="https://gitee.com/colovu/docker-${APP_NAME}" \
|
||||
org.opencontainers.image.documentation="https://gitee.com/colovu/docker-${APP_NAME}/blob/main/README.md" \
|
||||
maintainer="Endial Fang <endial@126.com>"
|
||||
|
||||
# 拷贝源仓库配置文件
|
||||
COPY etc /etc/
|
||||
|
||||
# 拷贝默认的通用脚本文件
|
||||
COPY .ci/common/alpine /
|
||||
|
||||
# 说明:
|
||||
# 虽然原始镜像包含 wget, 但该版本存在问题,下载部分资源(如redis)会报错,因此安装官方完整版
|
||||
@@ -43,7 +54,7 @@ RUN set -eux; \
|
||||
select_source ${APT_SOURCE}; \
|
||||
\
|
||||
# 安装编译环境及常用开发库
|
||||
install_pkg sudo wget git ca-certificates iproute2 net-tools nano dpkg gnupg \
|
||||
install_pkg sudo wget curl git ca-certificates iproute2 net-tools nano dpkg gnupg \
|
||||
dpkg-dev bash build-base cmake pkgconf \
|
||||
linux-headers cmocka-dev openssl-dev
|
||||
|
||||
|
||||
@@ -3,9 +3,13 @@
|
||||
#
|
||||
# Docker 镜像构建脚本 (仅linux/amd64)
|
||||
|
||||
# 编译后镜像名称
|
||||
IMAGE_NAME="abuilder"
|
||||
REGISTRY_URL="swr.cn-north-4.myhuaweicloud.com/colovu/"
|
||||
APT_SOURCE="ustc"
|
||||
# 依赖镜像的仓库地址(本镜像需要依赖原生 alpine 镜像)
|
||||
REGISTRY_URL="swr.cn-north-4.myhuaweicloud.com/img-sync/docker.io/"
|
||||
# 源仓库地址(本地编译时,使用阿里云源仓库)
|
||||
APT_SOURCE="aliyun"
|
||||
APP_VER="3.22"
|
||||
|
||||
# 获取发布版本标签
|
||||
get_release_tag() {
|
||||
@@ -46,16 +50,57 @@ get_image_tag() {
|
||||
fi
|
||||
}
|
||||
|
||||
# 构建amd64架构镜像
|
||||
# 根据当前系统架构构建镜像
|
||||
build() {
|
||||
local TAG=${1:-$(get_image_tag)}
|
||||
echo "Building image ${IMAGE_NAME}:${TAG} (linux/amd64)"
|
||||
|
||||
# 获取当前系统的架构
|
||||
local ARCH=$(uname -m)
|
||||
local PLATFORM=""
|
||||
case "$ARCH" in
|
||||
x86_64)
|
||||
PLATFORM="linux/amd64"
|
||||
;;
|
||||
aarch64|arm64)
|
||||
PLATFORM="linux/arm64"
|
||||
;;
|
||||
armv7l)
|
||||
PLATFORM="linux/arm/v7"
|
||||
;;
|
||||
*)
|
||||
PLATFORM="linux/amd64" # 默认为 amd64
|
||||
;;
|
||||
esac
|
||||
|
||||
podman build --platform linux/amd64 \
|
||||
# 如果在命令中指定了TAG,则使用相同的TAG作为APP_VER
|
||||
if [ -n "$1" ]; then
|
||||
APP_VER="$1"
|
||||
else
|
||||
# 获取当前分支名并判断是否为主分支
|
||||
local branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
|
||||
if [ "$branch" != "master" ] && [ "$branch" != "main" ]; then
|
||||
# 如果不是主分支,则使用分支名或标签名
|
||||
local tag=$(git describe --tags --abbrev=0 2>/dev/null)
|
||||
if [ -n "$tag" ] && [ "$(git rev-list -n 1 $tag 2>/dev/null)" = "$(git rev-parse HEAD)" ]; then
|
||||
# 如果当前提交正好是标签,则使用标签名
|
||||
APP_VER="$tag"
|
||||
else
|
||||
# 否则使用分支名
|
||||
APP_VER="$branch"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# 去除APP_VER中的v前缀,仅保留数字分段部分
|
||||
APP_VER=$(echo "$APP_VER" | sed 's/^v//')
|
||||
|
||||
echo "Building image ${IMAGE_NAME}:${TAG} (${PLATFORM}) with APP_VER=${APP_VER}"
|
||||
|
||||
podman build --platform ${PLATFORM} \
|
||||
--progress plain --force-rm \
|
||||
--build-arg REGISTRY_URL=${REGISTRY_URL} \
|
||||
--build-arg APT_SOURCE=${APT_SOURCE} \
|
||||
--build-arg LOCAL_URL=http://pkgs.colovu.com/dist \
|
||||
--build-arg APP_VER=${APP_VER} \
|
||||
-t ${IMAGE_NAME}:${TAG} \
|
||||
-t ${IMAGE_NAME}:latest \
|
||||
.
|
||||
@@ -63,47 +108,65 @@ build() {
|
||||
echo "Build complete"
|
||||
}
|
||||
|
||||
# 推送镜像到colovu仓库
|
||||
push_colovu() {
|
||||
local TAG=${1:-$(get_image_tag)}
|
||||
echo "Pushing ${IMAGE_NAME}:${TAG} to registry.colovu.com"
|
||||
|
||||
podman tag "${IMAGE_NAME}:${TAG}" "registry.colovu.com/library/${IMAGE_NAME}:${TAG}"
|
||||
podman push "registry.colovu.com/library/${IMAGE_NAME}:${TAG}"
|
||||
|
||||
podman tag "${IMAGE_NAME}:latest" "registry.colovu.com/library/${IMAGE_NAME}:latest"
|
||||
podman push "registry.colovu.com/library/${IMAGE_NAME}:latest"
|
||||
}
|
||||
|
||||
# 推送镜像到华为云仓库
|
||||
push_huawei() {
|
||||
local TAG=${1:-$(get_release_tag)}
|
||||
echo "Pushing ${IMAGE_NAME}:${TAG} to swr.cn-north-4.myhuaweicloud.com"
|
||||
|
||||
podman tag "${IMAGE_NAME}:${TAG}" "swr.cn-north-4.myhuaweicloud.com/colovu/${IMAGE_NAME}:${TAG}"
|
||||
podman push "swr.cn-north-4.myhuaweicloud.com/colovu/${IMAGE_NAME}:${TAG}"
|
||||
|
||||
podman tag "${IMAGE_NAME}:latest" "swr.cn-north-4.myhuaweicloud.com/colovu/${IMAGE_NAME}:latest"
|
||||
podman push "swr.cn-north-4.myhuaweicloud.com/colovu/${IMAGE_NAME}:latest"
|
||||
}
|
||||
|
||||
# 清理工作空间
|
||||
clean() {
|
||||
echo "Cleaning workspace..."
|
||||
podman images | grep "${IMAGE_NAME} " | awk '{print $3}' | xargs -L 1 podman rmi -f
|
||||
podman ps -a | grep "Exited" | awk '{print $1}' | xargs -L 1 podman rm
|
||||
podman images | grep '<none>' | awk '{print $3}' | xargs -L 1 podman rmi -f
|
||||
# 删除所有与 IMAGE_NAME 相关的镜像标签(包括带 localhost 前缀的)
|
||||
podman images --format "{{.Repository}}:{{.Tag}}" | grep -E "^(${IMAGE_NAME}|localhost/${IMAGE_NAME}):" | xargs -r podman rmi -f
|
||||
# 删除所有已退出的容器
|
||||
podman ps -a --format "{{.ID}}" --filter status=exited | xargs -r podman rm
|
||||
# 删除所有悬空镜像(dangling images)
|
||||
podman images --filter "dangling=true" -q | xargs -r podman rmi -f
|
||||
# 清理构建缓存
|
||||
podman system prune -f
|
||||
}
|
||||
|
||||
# 主函数中更新使用说明
|
||||
# 显示使用帮助信息
|
||||
show_help() {
|
||||
cat << EOF
|
||||
Usage: $0 [COMMAND] [TAG]
|
||||
|
||||
Docker 镜像构建和清理脚本
|
||||
|
||||
COMMANDS:
|
||||
build [tag] 构建镜像,可选择性指定标签,如未指定则自动生成
|
||||
clean 清理工作空间,删除相关镜像和无用容器
|
||||
help 显示此帮助信息
|
||||
|
||||
EXAMPLES:
|
||||
$0 build # 构建镜像,使用自动生成的标签
|
||||
$0 build mytag # 构建镜像,使用指定标签
|
||||
$0 clean # 清理工作空间
|
||||
$0 help # 显示帮助信息
|
||||
|
||||
DESCRIPTION:
|
||||
该脚本用于构建 alpine 镜像,支持自动生成标签,包含清理功能。
|
||||
构建的镜像名称为 ${IMAGE_NAME},默认会同时生成 latest 标签。
|
||||
脚本会根据当前系统架构自动构建对应架构的镜像,并设置 APP_VER 参数(自动去除v前缀):
|
||||
- 根据当前系统架构自动选择平台(linux/amd64, linux/arm64, linux/arm/v7 等)
|
||||
- 当在命令中指定TAG时,APP_VER使用相同的TAG值(去除v前缀)
|
||||
- 主分支(master/main)时使用 latest
|
||||
- 其他分支时使用分支名
|
||||
- 标签提交时使用标签名(去除v前缀)
|
||||
EOF
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
case "$1" in
|
||||
build) build "$2" ;; # 传递第二个参数作为标签
|
||||
clean) clean ;;
|
||||
push-cv) push_colovu "$2" ;;
|
||||
push-hw) push_huawei "$2" ;;
|
||||
push) push_colovu "$2"; push_huawei "$2" ;;
|
||||
*) echo "Usage: $0 {build [tag]|clean|push-cv [tag]|push-hw [tag]|push [tag]}"; exit 1 ;;
|
||||
help|-h|--help) show_help ;;
|
||||
*)
|
||||
if [ -z "$1" ]; then
|
||||
show_help
|
||||
else
|
||||
echo "Error: Unknown command '$1'"
|
||||
echo ""
|
||||
show_help
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
http://mirrors.aliyun.com/alpine/v3.22/main
|
||||
http://mirrors.aliyun.com/alpine/v3.22/community
|
||||
@@ -0,0 +1,2 @@
|
||||
http://dl-cdn.alpinelinux.org/alpine/v3.22/main
|
||||
http://dl-cdn.alpinelinux.org/alpine/v3.22/community
|
||||
@@ -0,0 +1,2 @@
|
||||
http://mirrors.ustc.edu.cn/alpine/v3.22/main
|
||||
http://mirrors.ustc.edu.cn/alpine/v3.22/community
|
||||
Reference in New Issue
Block a user