.github: Port common update action code from old coreos-overlay

This commit is contained in:
Krzesimir Nowak 2023-04-12 12:41:31 +02:00 committed by Thilo Fromm
parent adbd4a48f4
commit b6fc418fe5
3 changed files with 312 additions and 0 deletions

186
.github/workflows/common.sh vendored Normal file
View File

@ -0,0 +1,186 @@
#!/bin/bash
function fail() {
echo "$*" >/dev/stderr
exit 1
}
if [[ -z "${WORK_SCRIPTS_DIR:-}" ]]; then
fail "WORK_SCRIPTS_DIR env var unset. It should point to the scripts repo which will be updated."
fi
if [[ ! -d "${WORK_SCRIPTS_DIR:-}" ]]; then
fail "WORK_SCRIPTS_DIR env var does not point to a directory. It should point to the scripts repo which will be updated."
fi
readonly SDK_OUTER_TOPDIR="${WORK_SCRIPTS_DIR}"
readonly SDK_OUTER_OVERLAY="${SDK_OUTER_TOPDIR}/sdk_container/src/third_party/coreos-overlay"
readonly SDK_INNER_SRCDIR="/mnt/host/source/src"
readonly SDK_INNER_OVERLAY="${SDK_INNER_SRCDIR}/third_party/coreos-overlay"
readonly BUILDBOT_USERNAME="Flatcar Buildbot"
readonly BUILDBOT_USEREMAIL="buildbot@flatcar-linux.org"
# This enters the SDK container and executes the passed commands
# inside it. Requires PACKAGES_CONTAINER and SDK_NAME to be defined.
function enter() {
if [[ -z "${PACKAGES_CONTAINER}" ]]; then
fail "PACKAGES_CONTAINER env var unset. It should contain the name of the SDK container."
fi
if [[ -z "${SDK_NAME}" ]]; then
fail "SDK_NAME env var unset. It should contain the name of the SDK docker image."
fi
"${SDK_OUTER_TOPDIR}/run_sdk_container" \
-n "${PACKAGES_CONTAINER}" \
-C "${SDK_NAME}" \
"${@}"
}
# Return a valid ebuild file name for ebuilds of the given category name,
# package name, and the old version. If the single ebuild file already exists,
# then simply return that. If the file does not exist, then we should fall back
# to a similar file including $VERSION_OLD.
# For example, if VERSION_OLD == 1.0 and 1.0.ebuild does not exist, but only
# 1.0-r1.ebuild is there, then we figure out its most similar valid name by
# running "ls -1 ...*.ebuild | sort -ruV | head -n1".
function get_ebuild_filename() {
local pkg="${1}"; shift
local version="${1}"; shift
local name="${pkg##*/}"
local ebuild_basename="${pkg}/${name}-${version}"
if [[ ! -d "${pkg}" ]]; then
fail "No such package in '${PWD}': '${pkg}'"
fi
if [ -f "${ebuild_basename}.ebuild" ]; then
echo "${ebuild_basename}.ebuild"
else
ls -1 "${ebuild_basename}"*.ebuild | sort --reverse --unique --version-sort | head --lines 1
fi
}
function prepare_git_repo() {
git -C "${SDK_OUTER_TOPDIR}" config user.name "${BUILDBOT_USERNAME}"
git -C "${SDK_OUTER_TOPDIR}" config user.email "${BUILDBOT_USEREMAIL}"
}
# Regenerates a manifest file using an ebuild of a given package with
# a given version.
#
# Example:
# regenerate_manifest dev-lang/go 1.20.2
function regenerate_manifest() {
local pkg="${1}"; shift
local version="${1}"; shift
local name="${pkg##*/}"
local ebuild_file
ebuild_file="${SDK_INNER_OVERLAY}/${pkg}/${name}-${version}.ebuild"
enter ebuild "${ebuild_file}" manifest --force
}
function join_by() {
local delimiter="${1-}"
local first="${2-}"
if shift 2; then
printf '%s' "${first}" "${@/#/${delimiter}}";
fi
}
# Generates a changelog entry. Usually the changelog entry is in a
# following form:
#
# - <name> ([<version>](<url>))
#
# Thus first three parameters of this function should be the name,
# version and URL. The changelog entries are files, so the fourth
# parameter is a name that will be a part of the filename. It often is
# a lower-case variant of the first parameter.
#
# Example:
# generate_update_changelog Go 1.20.2 'https://go.dev/doc/devel/release#go1.20.2' go
#
# Sometimes there's a bigger jump in versions, like from 1.19.1 to
# 1.19.4, so it is possible to pass extra version and URL pairs for
# the intermediate versions:
#
# generate_update_changelog Go 1.19.4 'https://go.dev/doc/devel/release#go1.19.4' go \
# 1.19.2 'https://go.dev/doc/devel/release#go1.19.2' \
# 1.19.3 'https://go.dev/doc/devel/release#go1.19.3'
function generate_update_changelog() {
local name="${1}"; shift
local version="${1}"; shift
local url="${1}"; shift
local update_name="${1}"; shift
# rest of parameters are version and link pairs for old versions
local file
local -a old_links
file="changelog/updates/$(date '+%Y-%m-%d')-${update_name}-${version}-update.md"
if [[ -d changelog/updates ]]; then
printf '%s %s ([%s](%s)' '-' "${name}" "${version}" "${url}" > "${file}"
if [[ $# -gt 0 ]]; then
echo -n ' (includes ' >> "${file}"
while [[ $# -gt 1 ]]; do
old_links+=( "[${1}](${2})" )
shift 2
done
printf '%s' "$(join_by ', ' "${old_links[@]}")" >> "${file}"
echo -n ')' >> "${file}"
fi
echo ')' >> "${file}"
fi
}
# Regenerates manifest for given package, and commits changes made for
# that package. If there are new entries in changelog directory, these
# are committed too. Another two parameters are old and new versions
# of the package.
#
# Example:
# commit_changes dev-lang/go 1.19.1 1.19.4
#
# Sometimes more files need to be added to the commit. In such cases
# extra paths can be specified and those will be passed to "git
# add". If an extra path is relative, it will be relative the overlay
# directory in the scripts repo. In order to use globs, it better to
# make sure that that absolute path is passed.
#
# commit_changes dev-lang/go 1.19.1 1.19.4 \
# some/extra/directory \
# some/file \
# "${PWD}/some/globs"*'-suffix'
function commit_changes() {
local pkg="${1}"; shift
local old_version="${1}"; shift
local new_version="${1}"; shift
# rest of parameters are additional directories to add to the commit
local name="${pkg##*/}"
regenerate_manifest "${pkg}" "${new_version}"
pushd "${SDK_OUTER_OVERLAY}"
git add "${pkg}"
if [[ -d changelog ]]; then
git add changelog
fi
for dir; do
git add "${dir}"
done
git commit -m "${pkg}: Update from ${old_version} to ${new_version}"
popd
}
# Prints the status of the git repo and cleans it up - reverts
# uncommitted changes, removes untracked files. It's usually called at
# the end of a script making changes to the repository in order to
# avoid unwanted changes to be a part of a PR created by the
# peter-evans/create-pull-request action that follows up.
function cleanup_repo() {
git -C "${SDK_OUTER_OVERLAY}" status
git -C "${SDK_OUTER_OVERLAY}" reset --hard HEAD
git -C "${SDK_OUTER_OVERLAY}" clean -ffdx
}

67
.github/workflows/figure-out-branch.sh vendored Executable file
View File

@ -0,0 +1,67 @@
#!/bin/bash
# Prints the following github outputs based on channel named passed to
# the script as a parameter.
#
# BRANCH is a name of the git branch related to the passed channel.
#
# SKIP tells whether the rest of the steps should be skipped, will be
# either 0 or 1.
#
# LINK is a link to release mirror for the following channel. Will be
# empty for main channel.
#
# LABEL is going to be mostly the same as the channel name, except
# that lts-old will be labeled as lts.
set -euo pipefail
if [[ ${#} -ne 1 ]]; then
echo "Expected a channel name as a parameter" >&2
exit 1
fi
channel_name="${1}"
skip=0
link=''
branch=''
label=''
case "${channel_name}" in
main)
branch='main'
;;
lts-old)
curl -fsSLO --retry-delay 1 --retry 60 --retry-connrefused --retry-max-time 60 --connect-timeout 20 'https://lts.release.flatcar-linux.net/lts-info'
if [[ $(grep -e ':supported' lts-info | wc -l) -le 1 ]]; then
# Only one supported LTS, skip this workflow run
# as 'lts' matrix branch will handle updating the only
# supported LTS.
skip=1
else
line=$(grep -e ':supported' lts-info | sort -V | head -n 1)
major=$(awk -F: '{print $1}' <<<"${line}")
year=$(awk -F: '{print $2}' <<<"${line}")
branch="flatcar-${major}"
link="https://lts.release.flatcar-linux.net/amd64-usr/current-${year}"
label='lts'
fi
rm -f lts-info
;;
alpha|beta|stable|lts)
link="https://${channel_name}.release.flatcar-linux.net/amd64-usr/current"
major=$(curl -sSL "${link}/version.txt" | awk -F= '/FLATCAR_BUILD=/{ print $2 }')
branch="flatcar-${major}"
;;
*)
echo "Unknown channel '${channel_name}'" >&2
exit 1
esac
if [[ -z "${label}" ]]; then
label="${channel_name}"
fi
echo "BRANCH=${branch}" >>"${GITHUB_OUTPUT}"
echo "SKIP=${skip}" >>"${GITHUB_OUTPUT}"
echo "LINK=${link}" >>"${GITHUB_OUTPUT}"
echo "LABEL=${label}" >>"${GITHUB_OUTPUT}"

59
.github/workflows/setup-flatcar-sdk.sh vendored Executable file
View File

@ -0,0 +1,59 @@
#!/bin/bash
set -euo pipefail
if [[ -z "${WORK_SCRIPTS_DIR:-}" ]]; then
echo 'WORK_SCRIPTS_DIR unset, should be pointing to the scripts repo which will be updated'
fi
sudo ln -sfn /bin/bash /bin/sh
sudo apt-get update
sudo apt-get install -y ca-certificates curl git gnupg lbzip2 lsb-release \
qemu-user-static
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io \
docker-compose-plugin
pushd "${WORK_SCRIPTS_DIR}"
source ci-automation/ci_automation_common.sh
source sdk_container/.repo/manifests/version.txt
# run_sdk_container requires a tag to exist in the repo it resides,
# which may not be the case for forked repos. Add some fake tag in
# this case.
if ! git describe --tags &>/dev/null; then
git tag "${CHANNEL}-${FLATCAR_VERSION}"
fi
arch="amd64"
sdk_name="flatcar-sdk-${arch}"
if [[ "${CHANNEL}" = 'main' ]]; then
# for main channel, pull in alpha SDK
MIRROR_LINK='https://alpha.release.flatcar-linux.net/amd64-usr/current'
fi
# Pin the docker image version to that of the latest release in the channel.
docker_sdk_vernum="$(curl -s -S -f -L "${MIRROR_LINK}/version.txt" \
| grep -m 1 FLATCAR_SDK_VERSION= | cut -d = -f 2- \
)"
docker_image_from_registry_or_buildcache "${sdk_name}" "${docker_sdk_vernum}"
sdk_full_name="$(docker_image_fullname "${sdk_name}" "${docker_sdk_vernum}")"
docker_vernum="$(vernum_to_docker_image_version "${FLATCAR_VERSION_ID}")"
packages_container_name="flatcar-packages-${arch}-${docker_vernum}"
popd
echo "PACKAGES_CONTAINER=${packages_container_name}" >>"${GITHUB_OUTPUT}"
echo "SDK_NAME=${sdk_full_name}" >>"${GITHUB_OUTPUT}"