archlinux-docker/.gitlab-ci.yml

314 lines
10 KiB
YAML

default:
image: "archlinux:latest"
stages:
- cleanup
- lint
- rootfs
- image
- test
- release
- publish
cleanup:
stage: cleanup
tags:
- secure
only:
refs:
- schedules
variables:
- $CLEANUP_PACKAGE_REGISTRY == "TRUE"
before_script:
- pacman -Syu --noconfirm jq
script:
- |
for id in $(curl --silent --fail --show-error "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages?per_page=100&order_by=created_at&sort=asc" | jq '.[] | select(.created_at | split("T")[0] | . < (now-60*60*24*60|strflocaltime("%Y-%m-%d"))) | .id'); do
curl --silent --fail --show-error --request DELETE --header "PRIVATE-TOKEN: ${GITLAB_PROJECT_TOKEN}" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/${id}"
done
lint:
stage: lint
image: hadolint/hadolint:latest-alpine
# DL3018: We don't need alpine version pins
script: hadolint --ignore DL3018 Dockerfile.template
except:
- releases
- tags
get_version:
stage: .pre
script:
- |
# If we're building a tagged release, use the tag (without the 'v' prefix) as the
# BUILD_VERSION. Otherwise, determine a new BUILD_VERSION.
if [[ -n "$CI_COMMIT_TAG" ]]; then
echo "BUILD_VERSION=${CI_COMMIT_TAG/v/}" > build.env
else
echo "BUILD_VERSION=$(date +%Y%m%d).0.$CI_JOB_ID" > build.env
fi
- export $(< build.env)
- echo "PACKAGE_REGISTRY_URL=${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/rootfs/${BUILD_VERSION}" >> build.env
artifacts:
reports:
dotenv: build.env
.rootfs:
stage: rootfs
before_script:
- pacman -Syu --noconfirm make devtools fakechroot fakeroot
script:
- make $PWD/output/Dockerfile.$GROUP
artifacts:
paths:
- output/*
expire_in: 2h
rootfs:
extends: .rootfs
except:
- master
- releases
- schedules
- tags
parallel:
matrix:
- GROUP: [base, base-devel]
rootfs:secure:
extends: .rootfs
tags:
- secure
only:
- master
- schedules
except:
- tags
- releases
parallel:
matrix:
- GROUP: [base, base-devel]
.image:
stage: image
image:
name: gcr.io/kaniko-project/executor:v1.7.0-debug
entrypoint: [""]
script:
- /kaniko/executor
--force
--ignore-var-run="false"
--context $CI_PROJECT_DIR/output
--dockerfile $CI_PROJECT_DIR/output/Dockerfile.$GROUP
--destination $CI_REGISTRY_IMAGE:$GROUP-$CI_COMMIT_REF_SLUG
image:build:
extends: .image
except:
- master
- releases
- schedules
- tags
parallel:
matrix:
- GROUP: [base, base-devel]
before_script:
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
image:build:secure:
extends: .image
tags:
- secure
only:
- master
- schedules
except:
- tags
parallel:
matrix:
- GROUP: [base, base-devel]
before_script:
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$GITLAB_PROJECT_USER\",\"password\":\"$GITLAB_PROJECT_TOKEN\"}}}" > /kaniko/.docker/config.json
# Build and publish to the Arch Linux group namespace: https://hub.docker.com/r/archlinux/archlinux
image:publish:secure:
extends: .image
retry: 2
tags:
- secure
only:
- tags
parallel:
matrix:
- GROUP: [base, base-devel]
before_script:
- echo "{\"auths\":{\"https://index.docker.io/v1/\":{\"username\":\"$DOCKERHUB_USERNAME\",\"password\":\"$DOCKERHUB_ACCESS_TOKEN\"}}}" > /kaniko/.docker/config.json
script:
- LATEST=""
- if [[ "$GROUP" == "base" ]]; then
LATEST="--destination archlinux/archlinux:latest";
fi
- /kaniko/executor
--force
--ignore-var-run="false"
--context $CI_PROJECT_DIR
--dockerfile $CI_PROJECT_DIR/Dockerfile.$GROUP
--destination archlinux/archlinux:$GROUP
--destination archlinux/archlinux:$GROUP-$BUILD_VERSION
$LATEST
.test:
stage: test
dependencies: []
only:
variables:
# Workaround for https://gitlab.com/gitlab-org/gitlab/-/issues/259663
# This is fine as at this point we're sure that the release works anyway.
- $GITLAB_USER_EMAIL != "project10185_bot2@example.com"
except:
refs:
- releases
- tags
.test-script: &test-script
- test "$(cat /etc/group | wc -l)" -gt 10
- test "$(cat /etc/passwd | wc -l)" -gt 10
- pacman -Sy
- pacman -Qqk
- pacman -Syu --noconfirm docker grep
- docker -v
- id -u http
- locale | grep -q UTF-8
test:base:
extends: .test
image: $CI_REGISTRY_IMAGE:base-$CI_COMMIT_REF_SLUG
script:
- *test-script
test:base-devel:
extends: .test
image: $CI_REGISTRY_IMAGE:base-devel-$CI_COMMIT_REF_SLUG
script:
- *test-script
- gcc -v
- g++ -v
- make -v
release:
stage: release
image: registry.gitlab.com/gitlab-org/release-cli:latest
tags:
- secure
only:
refs:
- schedules
variables:
- $PUBLISH_ARCHLINUX_REPOSITORY == "TRUE"
- $PUBLISH_OFFICIAL_LIBRARY == "TRUE"
before_script:
- apk update
- apk add jq curl httpie
script:
- |
# Update the description on https://hub.docker.com/r/archlinux/archlinux
TOKEN="$(http --ignore-stdin POST https://hub.docker.com/v2/users/login username="${DOCKERHUB_USERNAME}" password="${DOCKERHUB_PASSWORD}" | jq -er .token)"
http --ignore-stdin PATCH https://hub.docker.com/v2/repositories/archlinux/archlinux/ Authorization:"JWT ${TOKEN}" full_description="$(cat README.md)"
# Upload rootfs to the Generic Packages Repository
for group in base base-devel; do
sed -i "s|${group}.tar.xz|${group}-${BUILD_VERSION}.tar.xz|" output/${group}.tar.xz.SHA256
echo "Uploading ${group}.tar.xz"
curl -sSf --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file output/${group}.tar.xz ${PACKAGE_REGISTRY_URL}/${group}-${BUILD_VERSION}.tar.xz
echo "Uploading ${group}.tar.xz.SHA256"
curl -sSf --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file output/${group}.tar.xz.SHA256 ${PACKAGE_REGISTRY_URL}/${group}-${BUILD_VERSION}.tar.xz.SHA256
sed "/TEMPLATE_ROOTFS_FILE/d" Dockerfile.template > output/Dockerfile.${group}
package_url=$(./ci/get-public-download-for-generic-package.sh ${group}-${BUILD_VERSION}.tar.xz)
sed -i "s|TEMPLATE_ROOTFS_RELEASE_URL|https://gitlab.archlinux.org/archlinux/archlinux-docker/-/releases/v${BUILD_VERSION}|" output/Dockerfile.${group}
sed -i "s|TEMPLATE_ROOTFS_DOWNLOAD|ROOTFS=\"\$(curl -sOJL -w \"%{filename_effective}\" \"${package_url}\")\"|" output/Dockerfile.${group}
sed -i "s|TEMPLATE_ROOTFS_HASH|$(cat output/${group}.tar.xz.SHA256)|" output/Dockerfile.${group}
done
- >
curl -sSf --request POST -o commit-response.json
--header "PRIVATE-TOKEN: ${GITLAB_PROJECT_TOKEN}"
--form "branch=releases"
--form "commit_message=Release ${BUILD_VERSION}"
--form "actions[][action]=update"
--form "actions[][file_path]=Dockerfile.base"
--form "actions[][content]=<output/Dockerfile.base"
--form "actions[][action]=update"
--form "actions[][file_path]=Dockerfile.base-devel"
--form "actions[][content]=<output/Dockerfile.base-devel"
--form "actions[][action]=update"
--form "actions[][file_path]=.gitlab-ci.yml"
--form "actions[][content]=<.gitlab-ci.yml"
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/repository/commits"
- echo "BUILD_COMMIT=$(jq -r '.id' commit-response.json)" >> build.env
- |
base_url=$(./ci/get-public-download-for-generic-package.sh base-${BUILD_VERSION}.tar.xz)
echo "${base_url}"
base_sha_url=$(./ci/get-public-download-for-generic-package.sh base-${BUILD_VERSION}.tar.xz.SHA256)
echo "${base_sha_url}"
base_devel_url=$(./ci/get-public-download-for-generic-package.sh base-devel-${BUILD_VERSION}.tar.xz)
echo "${base_devel_url}"
base_devel_sha_url=$(./ci/get-public-download-for-generic-package.sh base-devel-${BUILD_VERSION}.tar.xz.SHA256)
echo "${base_devel_sha_url}"
# TODO: We should actually be able to do something like \"url\":\"${PACKAGE_REGISTRY_URL}/base-${BUILD_VERSION}.tar.xz\"
# But it doesn't appear that those downloads are public. I consider this a bug and hopefully it's fixed in a future version!
echo "Creating release"
release-cli --private-token "${GITLAB_PROJECT_TOKEN}" create \
--name "Release ${BUILD_VERSION}" \
--description "Release ${BUILD_VERSION}" \
--tag-name v${BUILD_VERSION} --ref "releases" \
--assets-link "{\"name\":\"base-${BUILD_VERSION}.tar.xz\",\"url\":\"${base_url}\"}" \
--assets-link "{\"name\":\"base-${BUILD_VERSION}.tar.xz.SHA256\",\"url\":\"${base_sha_url}\"}" \
--assets-link "{\"name\":\"base-devel-${BUILD_VERSION}.tar.xz\",\"url\":\"${base_devel_url}\"}" \
--assets-link "{\"name\":\"base-devel-${BUILD_VERSION}.tar.xz.SHA256\",\"url\":\"${base_devel_sha_url}\"}"
artifacts:
reports:
dotenv: build.env
# Publish to the official Docker namespace: https://hub.docker.com/_/archlinux
publish:
stage: publish
only:
refs:
- schedules
variables:
- $PUBLISH_OFFICIAL_LIBRARY == "TRUE"
before_script:
- export | grep -q BUILD_VERSION=
- export | grep -q BUILD_COMMIT=
- test -n "$BUILD_VERSION"
- test -n "$BUILD_COMMIT"
- test -n "$GITHUB_TOKEN"
- pacman -Syu --noconfirm github-cli git gettext
- git config --global user.email "github@archlinux.org"
- git config --global user.name "Arch Linux Technical User"
script:
- mkdir official-images
- cd official-images
- git init
- 'git remote add origin "https://x-access-token:${GITHUB_TOKEN}@github.com/archlinux/official-images.git"'
- git fetch https://github.com/docker-library/official-images.git
- git reset --hard FETCH_HEAD
- head="release/${BUILD_VERSION}"
- git checkout -b "$head"
- envsubst < ../docker-library.template > library/archlinux
- git diff
- git add library/archlinux
- maintainers="$(grep \(@ ../docker-library.template | cut -d\( -f2 | cut -d\) -f1 | xargs)"
- test -n "$maintainers"
- 'git commit
-m "archlinux: Release ${BUILD_VERSION}"
-m "This is an automated release [1]."
-m "[1] ${CI_PROJECT_URL}/-/blob/master/.gitlab-ci.yml"'
- git push -u origin "$head"
- 'gh pr create
--repo docker-library/official-images
--title "$(git show --no-patch --format="%s")"
--body "$(printf "%s\n\n---\n\nMaintainers: ${maintainers}\n" "$(git show --no-patch --format="%b")")"
--base master
--head archlinux:"$head"'