1
0

ci: introduce

This commit is contained in:
Konstantin Demin 2024-05-28 14:46:02 +03:00
parent ab6edbd967
commit ea389edfee
Signed by: krd
GPG Key ID: 4D56F87A8BA65FD0
14 changed files with 398 additions and 0 deletions

21
.ci/build-all.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/sh
# SPDX-License-Identifier: Apache-2.0
# (c) 2024, Konstantin Demin
set -ef
[ -z "${CI_DEBUG}" ] || set -xv
r=0
TARGET_PLATFORMS=$(printf '%s' "${TARGET_PLATFORMS:?}" | tr ',' ' ')
for TARGET_PLATFORM in ${TARGET_PLATFORMS} ; do
export TARGET_PLATFORM
. .ci/envsh.build
.ci/build.sh || r=$?
[ "$r" = 0 ] || break
done
make ci-clean
exit "$r"

20
.ci/build.sh Executable file
View File

@ -0,0 +1,20 @@
#!/bin/sh
# SPDX-License-Identifier: Apache-2.0
# (c) 2024, Konstantin Demin
set -ef
[ -z "${CI_DEBUG}" ] || set -xv
mkdir -p dist
OUTDIR=dist
OUTSFX='-'$(printf '%s' "${TARGET_PLATFORM:?}" | tr '/' '-')
export OUTDIR OUTSFX
idle() {
nice -n +40 \
chrt -i 0 \
ionice -c 3 \
"$@"
}
idle make clean build || make clean build

44
.ci/envsh.build Normal file
View File

@ -0,0 +1,44 @@
#!/bin/sh
# SPDX-License-Identifier: Apache-2.0
# (c) 2024, Konstantin Demin
set -ef
unset GOAMD64 GOARM GOPPC64 GOMIPS GOMIPS64
## produce GOOS and GOARCH from TARGET_PLATFORM
unset GOOS GOARCH _variant
IFS=/ read -r GOOS GOARCH _variant <<-EOF
${TARGET_PLATFORM:?}
EOF
## verify that GOOS and GOARCH are not empty
: "${GOOS:?}" "${GOARCH:?}"
export GOOS GOARCH
## fill env with Go-related variables
if [ -n "${_variant}" ] ; then
case "${GOARCH}" in
amd64 )
export GOAMD64="${_variant}" ;;
arm )
export GOARM="${_variant#v}" ;;
ppc64 | ppc64le )
export GOPPC64="${_variant}" ;;
mips | mipsle )
export GOMIPS="${_variant}" ;;
mips64 | mips64le )
export GOMIPS64="${_variant}" ;;
esac
fi
unset _variant
unset RELMODE
while : ; do
[ -n "${CI_COMMIT_BRANCH}" ] || break
[ -n "${CI_REPO_DEFAULT_BRANCH}" ] || break
## RELMODE is for default branch only
[ "${CI_COMMIT_BRANCH}" = "${CI_REPO_DEFAULT_BRANCH}" ] || break
export RELMODE=1
break
done
[ -z "${CI_COMMIT_TAG}" ] || export RELMODE=1

66
.ci/envsh.common Normal file
View File

@ -0,0 +1,66 @@
#!/bin/sh
# SPDX-License-Identifier: Apache-2.0
# (c) 2024, Konstantin Demin
set -ef
## shifty-nifty shell goodies :)
## do same thing as GitLab does for CI_COMMIT_REF_SLUG:
## 1. lowercase string
## 2. replace not allowed chars with '-' (squeezing repeats)
## allowed chars are: `0-9`, `a-z` and '-'
## 3. remove leading and trailing '-' (if any)
## 4. truncate string up to 63 chars
## 5. remove trailing '-' (if any)
ref_slug() {
printf '%s' "${1:?}" \
| sed -Ez 's/^(.+)$/\L\1/;s/[^0-9a-z]+/-/g;s/^-//;s/-$//;s/^(.{1,63}).*$/\1/;s/-$//' \
| tr -d '\0'
}
## normalize image tag
## performs like ref_slug() except:
## - symbols '_' and '.' are allowed too
## - truncate string up to 96 chars
## - squeeze symbol sequences:
## - '-' has higher priority than surrounding (leading and trailing) symbols
## - first symbol in sequence has higher priority than following symbols
## NB: implementation is rather demonstrative than effective
image_tag_norm() {
printf '%s' "${1:?}" \
| sed -Ez 's/^(.+)$/\L\1/;s/[^0-9a-z_.]+/-/g' \
| sed -Ez 's/\.+/./g;s/_+/_/g;s/[_.]+-/-/g;s/-[_.]+/-/g;s/([_.])[_.]+/\1/g' \
| sed -Ez 's/^[_.-]//;s/[_.-]$//;s/^(.{1,95}).*$/\1/;s/[_.-]$//' \
| tr -d '\0'
}
## misc CI things
# CI_COMMIT_SHORT_SHA="${CI_COMMIT_SHA:0:8}"
CI_COMMIT_SHORT_SHA=$(printf '%s' "${CI_COMMIT_SHA}" | cut -c 1-8)
CI_COMMIT_REF_SLUG="$(ref_slug "${CI_COMMIT_BRANCH}")"
if [ -n "${CI_COMMIT_SOURCE_BRANCH}" ] ; then
CI_COMMIT_REF_SLUG="$(ref_slug "${CI_COMMIT_SOURCE_BRANCH}")"
fi
## image tag(s)
IMAGE_TAG="${CI_COMMIT_SHORT_SHA}-b${CI_PIPELINE_NUMBER}-${CI_COMMIT_REF_SLUG}"
EXTRA_TAGS=$(image_tag_norm "branch-${CI_COMMIT_BRANCH}")
if [ -n "${CI_COMMIT_TAG}" ] ; then
IMAGE_TAG="${CI_COMMIT_TAG}"
unset EXTRA_TAGS
## TODO: think about "latest" tag: it should be error-prone for "backward tag push"
# EXTRA_TAGS='latest'
else
if [ -n "${CI_COMMIT_SOURCE_BRANCH}" ] ; then
echo "Running on branch '${CI_COMMIT_SOURCE_BRANCH}'"
else
if [ "${CI_COMMIT_BRANCH}" != "${CI_REPO_DEFAULT_BRANCH}" ] ; then
echo "Running on branch '${CI_COMMIT_BRANCH}'"
else
IMAGE_TAG="${CI_COMMIT_SHORT_SHA}"
fi
fi
fi
IMAGE_TAG=$(image_tag_norm "${IMAGE_TAG}")
export CI_COMMIT_SHORT_SHA CI_COMMIT_REF_SLUG IMAGE_TAG EXTRA_TAGS

14
.ci/envsh.registry Normal file
View File

@ -0,0 +1,14 @@
#!/bin/sh
# SPDX-License-Identifier: Apache-2.0
# (c) 2024, Konstantin Demin
set -ef
## setup image registry authentication
export REGISTRY_AUTH_FILE="${PWD}/.ci/.auth.json"
if ! [ -s "${REGISTRY_AUTH_FILE}" ] ; then
if [ -z "${REGISTRY_AUTH}" ] ; then
echo 'REGISTRY_AUTH is missing'
exit 1
fi
printf '%s' "${REGISTRY_AUTH}" > "${REGISTRY_AUTH_FILE}"
fi

50
.ci/image-all.sh Executable file
View File

@ -0,0 +1,50 @@
#!/bin/sh
# SPDX-License-Identifier: Apache-2.0
# (c) 2024, Konstantin Demin
set -ef
[ -z "${CI_DEBUG}" ] || set -xv
: "${TARGET_PLATFORMS:?}"
. .ci/envsh.common
. .ci/envsh.registry
: "${IMAGE_NAME:?}" "${IMAGE_TAG:?}"
IMAGE="${IMAGE_NAME}:${IMAGE_TAG}"
## used by .ci/image.sh
export IMAGE_MANIFEST="${IMAGE}"
if buildah manifest exists "${IMAGE}" ; then
buildah manifest rm "${IMAGE}"
fi
buildah manifest create "${IMAGE}"
r=0
TARGET_PLATFORMS=$(printf '%s' "${TARGET_PLATFORMS}" | tr ',' ' ')
for TARGET_PLATFORM in ${TARGET_PLATFORMS} ; do
export TARGET_PLATFORM
. .ci/envsh.build
PLATFORM_SUFFIX='-'$(printf '%s' "${TARGET_PLATFORM}" | tr '/' '-')
export PLATFORM_SUFFIX
.ci/image.sh || r=$?
[ "$r" = 0 ] || break
buildah manifest add "${IMAGE}" "${IMAGE}${PLATFORM_SUFFIX}"
done
[ "$r" = 0 ] || exit "$r"
## list built image(s)
echo
echo 'IMAGES:'
echo
buildah images --all --noheading --format 'table {{.ID}} {{.Name}}:{{.Tag}} {{.Size}} {{.CreatedAtRaw}}' --filter "reference=${IMAGE_NAME}"
echo
buildah manifest push --all "${IMAGE}" "docker://${IMAGE}"

22
.ci/image.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/sh
# SPDX-License-Identifier: Apache-2.0
# (c) 2024, Konstantin Demin
set -ef
. .ci/envsh.registry
[ -z "${CI_DEBUG}" ] || set -xv
## produce _real_ BASE_IMAGE because "static-debian12:debug-nonroot" is not multiarch image (yet)
export BASE_IMAGE="${BASE_IMAGE:?}-${GOARCH:?}"
## build image
buildah bud \
-t "${IMAGE_NAME}:${IMAGE_TAG}${PLATFORM_SUFFIX}" \
-f ./Dockerfile.ci \
${IMAGE_MANIFEST:+ --manifest "${IMAGE_MANIFEST}" } \
--platform "${TARGET_PLATFORM}" \
--build-arg "TARGET_PLATFORM=${TARGET_PLATFORM}" \
--build-arg "PLATFORM_SUFFIX=${PLATFORM_SUFFIX}" \
--build-arg "BASE_IMAGE=${BASE_IMAGE}" \
--network=host

21
.ci/registry-login.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/sh
# SPDX-License-Identifier: Apache-2.0
# (c) 2024, Konstantin Demin
set -ef
[ -z "${CI_DEBUG}" ] || set -xv
unset _bin
for i in podman buildah skopeo ; do
if command -V "$i" >/dev/null ; then
_bin=$i
break
fi
done
: "${_bin:?}"
. .ci/envsh.registry
for i ; do
"${_bin}" login "$i" </dev/null
done

44
.ci/sync-all.sh Executable file
View File

@ -0,0 +1,44 @@
#!/bin/sh
# SPDX-License-Identifier: Apache-2.0
# (c) 2024, Konstantin Demin
set -ef
[ -z "${CI_DEBUG}" ] || set -xv
: "${IMAGE_NAME:?}" "${EXT_IMAGE_NAME:?}"
. .ci/envsh.common
. .ci/envsh.registry
image_src="docker://${IMAGE_NAME}"
image_dst="docker://${EXT_IMAGE_NAME}"
oci_dir="${PWD}/oci-layers"
image_interim="oci:${oci_dir}:$(basename "${IMAGE_NAME}"):${IMAGE_TAG}"
rm -rf "${oci_dir}" ; mkdir "${oci_dir}"
r=0
while : ; do
skopeo copy --all "${image_src}:${IMAGE_TAG}" "${image_interim}" || r=$?
[ "$r" = 0 ] || break
skopeo copy --all "${image_interim}" "${image_dst}:${IMAGE_TAG}" || r=$?
[ "$r" = 0 ] || break
for tag in ${EXTRA_TAGS} ; do
[ -n "${tag}" ] || continue
skopeo copy --all "${image_interim}" "${image_src}:${tag}" || r=$?
[ "$r" = 0 ] || break
skopeo copy --all "${image_interim}" "${image_dst}:${tag}" || r=$?
[ "$r" = 0 ] || break
done
break
done
rm -rf "${oci_dir}"
exit "$r"

View File

@ -1,3 +1,7 @@
.vscode/*
publish-nexus*
*.md
.ci/*
.woodpecker/*
.woodpecker.yml
dist/*

2
.gitignore vendored
View File

@ -1 +1,3 @@
/publish-nexus*
/.ci/.auth.json
/dist/

74
.woodpecker/.build.yml Normal file
View File

@ -0,0 +1,74 @@
when:
event: [ push, tag, cron, manual ]
variables:
- &image_name 'quay.krd.sh/krd/woodpecker-sonatype-nexus'
- &ext_image_name 'docker.io/rockdrilla/woodpecker-sonatype-nexus'
- &buildah_image 'quay.krd.sh/quay_io/containers/buildah:v1.35.3'
- &skopeo_image 'quay.krd.sh/quay_io/containers/skopeo:v1.15.0'
- &go_image 'quay.krd.sh/golang:1.22.3-bookworm'
- &base_image 'quay.krd.sh/gcr_io/distroless/static-debian12:debug-nonroot'
## value list depends on base image
## ref: https://github.com/GoogleContainerTools/distroless#debian-12
- &target_platforms 'linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x'
## kind of fixup (remove in near future)
## ref: https://github.com/woodpecker-ci/plugin-git/releases
clone:
git:
image: quay.krd.sh/docker_io/woodpeckerci/plugin-git:2.5.0
## NB: ${variable} expressions are subject to pre-processing.
## ref: https://woodpecker-ci.org/docs/usage/environment
steps:
- name: verify-registry-credentials
image: *skopeo_image
environment:
GOMAXPROCS: "4"
MALLOC_ARENA_MAX: "4"
secrets: [ REGISTRY_AUTH ]
commands:
- .ci/registry-login.sh quay.krd.sh docker.io
- name: build-all
image: *go_image
environment:
GOMAXPROCS: "4"
MALLOC_ARENA_MAX: "4"
##
TARGET_PLATFORMS: *target_platforms
## these secrets are server-wide
secrets: [ GOPRIVATE, GOPROXY, GOSUMDB ]
commands:
- .ci/build-all.sh
- name: image-all
image: *buildah_image
privileged: true
environment:
GOMAXPROCS: "4"
MALLOC_ARENA_MAX: "4"
##
BUILDAH_FORMAT: "docker"
TARGET_PLATFORMS: *target_platforms
BASE_IMAGE: *base_image
IMAGE_NAME: *image_name
commands:
- .ci/image-all.sh
- name: image-sync
image: *skopeo_image
environment:
GOMAXPROCS: "4"
MALLOC_ARENA_MAX: "4"
##
IMAGE_NAME: *image_name
EXT_IMAGE_NAME: *ext_image_name
commands:
- .ci/sync-all.sh
## personal tweaks :)
labels:
network: dmz

15
Dockerfile.ci Normal file
View File

@ -0,0 +1,15 @@
ARG TARGET_PLATFORM
ARG BASE_IMAGE
FROM --platform=${TARGET_PLATFORM} ${BASE_IMAGE}
ARG PLATFORM_SUFFIX
COPY /dist/publish-nexus${PLATFORM_SUFFIX} /bin/publish-nexus
ENV GOMAXPROCS=4 \
MALLOC_ARENA_MAX=4
ENTRYPOINT [ ]
CMD [ "/bin/publish-nexus" ]
USER nonroot:nonroot

View File

@ -1,5 +1,6 @@
# plugin-sonatype-nexus
[![build-status](https://ci.krd.sh/api/badges/5/status.svg)](https://ci.krd.sh/repos/5)
[![goreport](https://goreportcard.com/badge/git.krd.sh/krd/woodpecker-sonatype-nexus)](https://goreportcard.com/report/git.krd.sh/krd/woodpecker-sonatype-nexus)
[![docker-pulls](https://img.shields.io/docker/pulls/rockdrilla/woodpecker-sonatype-nexus)](https://hub.docker.com/r/rockdrilla/woodpecker-sonatype-nexus)
[![license](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)