Compare commits
14 Commits
2025.07-rc
...
snap
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90acabc390 | ||
|
|
a3d82ed485 | ||
|
|
f999808c5c | ||
|
|
fc213cf3b5 | ||
|
|
c6cd58b4a5 | ||
|
|
53d438936d | ||
|
|
4e875bf63e | ||
|
|
f9f05c7237 | ||
|
|
d40c8f0b87 | ||
|
|
327d8cb960 | ||
|
|
4674784f5b | ||
|
|
6776eb2133 | ||
|
|
290829cc0d | ||
|
|
6a3532c0db |
@@ -1,48 +1,73 @@
|
|||||||
# .gitlab-ci-release.yml
|
# .gitlab-ci-release.yml
|
||||||
|
|
||||||
# This single job handles the creation of both final releases and release candidates.
|
# Job to automatically update the version in the Makefile and push a commit.
|
||||||
# It determines which type of release to create based on the date.
|
# This runs on a schedule and only acts when a final release is due.
|
||||||
release:create:
|
version:bump:
|
||||||
stage: release
|
stage: version_bump
|
||||||
# We use the official release-cli image provided by GitLab.
|
image: alpine:3.18 # A small image with git and bash
|
||||||
image: registry.gitlab.com/gitlab-org/release-cli:latest
|
|
||||||
rules:
|
rules:
|
||||||
# This job only runs on scheduled pipelines that target the 'master' branch.
|
# Run only on scheduled pipelines targeting the 'master' branch.
|
||||||
- if: '$CI_PIPELINE_SOURCE == "schedule" && $CI_COMMIT_REF_NAME == "master"'
|
- if: '$CI_PIPELINE_SOURCE == "schedule" && $CI_COMMIT_REF_NAME == "master"'
|
||||||
script:
|
script:
|
||||||
- |
|
- |
|
||||||
echo "🚀 Checking release conditions for pipeline on branch '$CI_COMMIT_REF_NAME'..."
|
echo "Checking if a final release is scheduled today..."
|
||||||
# Use %-m, %-u, %-d to avoid issues with zero-padding (e.g., '08' being an invalid octal number).
|
|
||||||
MONTH=$(date +%-m)
|
MONTH=$(date +%-m)
|
||||||
DAY_OF_WEEK=$(date +%-u) # 1=Monday, 7=Sunday
|
DAY_OF_WEEK=$(date +%-u)
|
||||||
DAY_OF_MONTH=$(date +%-d)
|
DAY_OF_MONTH=$(date +%-d)
|
||||||
|
|
||||||
# FINAL RELEASE: Occurs on the first Monday of an even-numbered month.
|
# Only proceed on the first Monday of an even-numbered month.
|
||||||
# 1. The month is even (e.g., February, April...).
|
if ! { [ $((MONTH % 2)) -eq 0 ] && [ "$DAY_OF_WEEK" -eq 1 ] && [ "$DAY_OF_MONTH" -le 7 ]; }; then
|
||||||
# 2. The day of the week is Monday.
|
echo "Not a final release day. Nothing to do."
|
||||||
# 3. The day is within the first 7 days of the month.
|
exit 0
|
||||||
if [ $((MONTH % 2)) -eq 0 ] && [ "$DAY_OF_WEEK" -eq 1 ] && [ "$DAY_OF_MONTH" -le 7 ]; then
|
|
||||||
|
|
||||||
# This is a Final Release
|
|
||||||
TAG_NAME=$(date +%Y.%m)
|
|
||||||
RELEASE_TITLE="Release $TAG_NAME"
|
|
||||||
echo "✅ Conditions met for a Final Release. Creating tag: $TAG_NAME"
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
# This is a Release Candidate (RC)
|
|
||||||
# RC index is calculated based on the day of the month:
|
|
||||||
# Days 1-14 -> rc1, Days 15-28 -> rc2, etc.
|
|
||||||
RC_INDEX=$(( (DAY_OF_MONTH - 1) / 14 + 1 ))
|
|
||||||
TAG_NAME="$(date +%Y.%m)-rc${RC_INDEX}"
|
|
||||||
RELEASE_TITLE="Release Candidate $TAG_NAME"
|
|
||||||
echo "📝 Conditions met for a Release Candidate. Creating tag: $TAG_NAME"
|
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Executing release-cli to create the release..."
|
echo "✅ Final release day detected. Updating Makefile..."
|
||||||
|
|
||||||
|
# Set up Git
|
||||||
|
apk add --no-cache git
|
||||||
|
git config --global user.name "GitLab CI"
|
||||||
|
git config --global user.email "gitlab-ci@${CI_SERVER_HOST}"
|
||||||
|
|
||||||
|
# Set the new version details
|
||||||
|
NEW_VERSION=$(date +%Y)
|
||||||
|
NEW_PATCHLEVEL=$(printf "%02d" $MONTH)
|
||||||
|
|
||||||
|
# Use sed to update the Makefile
|
||||||
|
sed -i "s/^VERSION = .*/VERSION = $NEW_VERSION/" Makefile
|
||||||
|
sed -i "s/^PATCHLEVEL = .*/PATCHLEVEL = $NEW_PATCHLEVEL/" Makefile
|
||||||
|
sed -i "s/^SUBLEVEL = .*/SUBLEVEL =/" Makefile
|
||||||
|
sed -i "s/^EXTRAVERSION = .*/EXTRAVERSION =/" Makefile
|
||||||
|
|
||||||
|
# If there are no changes, exit.
|
||||||
|
if git diff --quiet Makefile; then
|
||||||
|
echo "Makefile is already up-to-date."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Commit and push the changes
|
||||||
|
echo "Pushing version bump to master branch..."
|
||||||
|
git add Makefile
|
||||||
|
COMMIT_MESSAGE="chore: Bump version to $NEW_VERSION.$NEW_PATCHLEVEL"
|
||||||
|
git commit -m "$COMMIT_MESSAGE"
|
||||||
|
# The GIT_WRITE_TOKEN is a variable you need to create (see setup below)
|
||||||
|
git push "https://gitlab-ci-token:${GIT_WRITE_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git" HEAD:master
|
||||||
|
|
||||||
|
# Job to create the release. This job now triggers from the commit pushed by the 'version:bump' job.
|
||||||
|
release:create:
|
||||||
|
stage: release
|
||||||
|
image: registry.gitlab.com/gitlab-org/release-cli:latest
|
||||||
|
rules:
|
||||||
|
# Run only on commits to master with a specific commit message.
|
||||||
|
- if: '$CI_COMMIT_BRANCH == "master" && $CI_COMMIT_MESSAGE =~ /^chore: Bump version to/'
|
||||||
|
script:
|
||||||
|
- |
|
||||||
|
echo "🚀 Release commit detected. Creating GitLab Release..."
|
||||||
|
# Extract the tag name directly from the commit message (e.g., "2025.08")
|
||||||
|
TAG_NAME=$(echo "$CI_COMMIT_MESSAGE" | sed -n 's/chore: Bump version to //p')
|
||||||
|
RELEASE_TITLE="Release $TAG_NAME"
|
||||||
|
|
||||||
release-cli create \
|
release-cli create \
|
||||||
--name "$RELEASE_TITLE" \
|
--name "$RELEASE_TITLE" \
|
||||||
--tag-name "$TAG_NAME" \
|
--tag-name "$TAG_NAME" \
|
||||||
--description "Automated release created by GitLab CI. Based on commit $CI_COMMIT_SHORT_SHA on the '$CI_COMMIT_REF_NAME' branch." \
|
--description "Automated release created by GitLab CI for commit $CI_COMMIT_SHORT_SHA." \
|
||||||
--ref "$CI_COMMIT_SHA"
|
--ref "$CI_COMMIT_SHA"
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ stages:
|
|||||||
- test.py
|
- test.py
|
||||||
- sjg-lab
|
- sjg-lab
|
||||||
- world build
|
- world build
|
||||||
|
- version_bump
|
||||||
- release
|
- release
|
||||||
|
|
||||||
.buildman_and_testpy_template: &buildman_and_testpy_dfn
|
.buildman_and_testpy_template: &buildman_and_testpy_dfn
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ CONFIG_SPL_DM_MAILBOX=y
|
|||||||
CONFIG_SPL_POWER_DOMAIN=y
|
CONFIG_SPL_POWER_DOMAIN=y
|
||||||
CONFIG_SPL_RAM_DEVICE=y
|
CONFIG_SPL_RAM_DEVICE=y
|
||||||
CONFIG_SPL_YMODEM_SUPPORT=y
|
CONFIG_SPL_YMODEM_SUPPORT=y
|
||||||
CONFIG_CMD_BOOTEFI_SELFTEST=y
|
|
||||||
CONFIG_CMD_NVEDIT_EFI=y
|
CONFIG_CMD_NVEDIT_EFI=y
|
||||||
CONFIG_CMD_DFU=y
|
CONFIG_CMD_DFU=y
|
||||||
CONFIG_CMD_GPIO=y
|
CONFIG_CMD_GPIO=y
|
||||||
|
|||||||
@@ -38,6 +38,6 @@
|
|||||||
|
|
||||||
exec labgrid-client -V do-bootstrap ${bootstrap:-1} -V do-build ${build:-1} \
|
exec labgrid-client -V do-bootstrap ${bootstrap:-1} -V do-build ${build:-1} \
|
||||||
-V do-send ${send:-0} -V do-clean ${clean:-0} ${vars} \
|
-V do-send ${send:-0} -V do-clean ${clean:-0} ${vars} \
|
||||||
-V process-limit ${BUILDMAN_PROCESS_LIMIT:-0} \
|
-V process-limit ${BUILDMAN_PROCESS_LIMIT:-0} ${log_output} ${V} \
|
||||||
-r "${U_BOOT_BOARD_IDENTITY}" ${strategy} ${verbose} -a console \
|
-r "${U_BOOT_BOARD_IDENTITY}" ${strategy} ${verbose} -a console \
|
||||||
${console_log}
|
${console_log}
|
||||||
|
|||||||
@@ -87,6 +87,9 @@ def pytest_addoption(parser):
|
|||||||
help='Compile U-Boot before running tests')
|
help='Compile U-Boot before running tests')
|
||||||
parser.addoption('--buildman', default=False, action='store_true',
|
parser.addoption('--buildman', default=False, action='store_true',
|
||||||
help='Use buildman to build U-Boot (assuming --build is given)')
|
help='Use buildman to build U-Boot (assuming --build is given)')
|
||||||
|
parser.addoption(
|
||||||
|
'-E', '--allow-exceptions', '-E', default=False, action='store_true',
|
||||||
|
help='Avoid catching exceptions with test failures')
|
||||||
parser.addoption('--gdbserver', default=None,
|
parser.addoption('--gdbserver', default=None,
|
||||||
help='Run sandbox under gdbserver. The argument is the channel '+
|
help='Run sandbox under gdbserver. The argument is the channel '+
|
||||||
'over which gdbserver should communicate, e.g. localhost:1234')
|
'over which gdbserver should communicate, e.g. localhost:1234')
|
||||||
@@ -167,7 +170,7 @@ def get_details(config):
|
|||||||
if build_dir_extra:
|
if build_dir_extra:
|
||||||
env['U_BOOT_BUILD_DIR_EXTRA'] = build_dir_extra
|
env['U_BOOT_BUILD_DIR_EXTRA'] = build_dir_extra
|
||||||
|
|
||||||
# Make sure the script sees that it is being run from pytest
|
# Make sure the script sees that it is being run from pytest
|
||||||
env['U_BOOT_SOURCE_DIR'] = source_dir
|
env['U_BOOT_SOURCE_DIR'] = source_dir
|
||||||
|
|
||||||
proc = subprocess.run(cmd, stdout=subprocess.PIPE,
|
proc = subprocess.run(cmd, stdout=subprocess.PIPE,
|
||||||
@@ -336,6 +339,7 @@ def pytest_configure(config):
|
|||||||
ubconfig.connection_ok = True
|
ubconfig.connection_ok = True
|
||||||
ubconfig.timing = config.getoption('timing')
|
ubconfig.timing = config.getoption('timing')
|
||||||
ubconfig.role = config.getoption('role')
|
ubconfig.role = config.getoption('role')
|
||||||
|
ubconfig.allow_exceptions = config.getoption('allow_exceptions')
|
||||||
|
|
||||||
env_vars = (
|
env_vars = (
|
||||||
'board_type',
|
'board_type',
|
||||||
@@ -507,6 +511,9 @@ def ubman(request):
|
|||||||
if not ubconfig.connection_ok:
|
if not ubconfig.connection_ok:
|
||||||
pytest.skip('Cannot get target connection')
|
pytest.skip('Cannot get target connection')
|
||||||
return None
|
return None
|
||||||
|
if ubman_fix.config.allow_exceptions:
|
||||||
|
ubman_fix.ensure_spawned()
|
||||||
|
return ubman_fix
|
||||||
try:
|
try:
|
||||||
ubman_fix.ensure_spawned()
|
ubman_fix.ensure_spawned()
|
||||||
except OSError as err:
|
except OSError as err:
|
||||||
@@ -880,20 +887,23 @@ def pytest_runtest_protocol(item, nextitem):
|
|||||||
test_list.append(item.name)
|
test_list.append(item.name)
|
||||||
tests_not_run.remove(item.name)
|
tests_not_run.remove(item.name)
|
||||||
|
|
||||||
try:
|
if ubman_fix.config.allow_exceptions:
|
||||||
msg_log(msg)
|
msg_log(msg)
|
||||||
except:
|
else:
|
||||||
# If something went wrong with logging, it's better to let the test
|
try:
|
||||||
# process continue, which may report other exceptions that triggered
|
msg_log(msg)
|
||||||
# the logging issue (e.g. ubman_fix.log wasn't created). Hence, just
|
except:
|
||||||
# squash the exception. If the test setup failed due to e.g. syntax
|
# If something went wrong with logging, it's better to let the test
|
||||||
# error somewhere else, this won't be seen. However, once that issue
|
# process continue, which may report other exceptions that triggered
|
||||||
# is fixed, if this exception still exists, it will then be logged as
|
# the logging issue (e.g. ubman_fix.log wasn't created). Hence, just
|
||||||
# part of the test's stdout.
|
# squash the exception. If the test setup failed due to e.g. syntax
|
||||||
import traceback
|
# error somewhere else, this won't be seen. However, once that issue
|
||||||
print('Exception occurred while logging runtest status:')
|
# is fixed, if this exception still exists, it will then be logged
|
||||||
traceback.print_exc()
|
# as part of the test's stdout.
|
||||||
# FIXME: Can we force a test failure here?
|
import traceback
|
||||||
|
print('Exception occurred while logging runtest status:')
|
||||||
|
traceback.print_exc()
|
||||||
|
# FIXME: Can we force a test failure here?
|
||||||
|
|
||||||
log.end_section(item.name)
|
log.end_section(item.name)
|
||||||
|
|
||||||
|
|||||||
@@ -60,14 +60,11 @@ class ConsoleSandbox(ConsoleBase):
|
|||||||
cmd += self.sandbox_flags
|
cmd += self.sandbox_flags
|
||||||
return Spawn(cmd, cwd=self.config.source_dir, decode_signal=True)
|
return Spawn(cmd, cwd=self.config.source_dir, decode_signal=True)
|
||||||
|
|
||||||
def restart_uboot_with_flags(self, flags, expect_reset=False, use_dtb=True):
|
def restart_uboot_with_flags(self, flags, use_dtb=True):
|
||||||
"""Run U-Boot with the given command-line flags
|
"""Run U-Boot with the given command-line flags
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
flags: List of flags to pass, each a string
|
flags: List of flags to pass, each a string
|
||||||
expect_reset: Boolean indication whether this boot is expected
|
|
||||||
to be reset while the 1st boot process after main boot before
|
|
||||||
prompt. False by default.
|
|
||||||
use_dtb: True to use a device tree file, False to run without one
|
use_dtb: True to use a device tree file, False to run without one
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -77,7 +74,7 @@ class ConsoleSandbox(ConsoleBase):
|
|||||||
try:
|
try:
|
||||||
self.sandbox_flags = flags
|
self.sandbox_flags = flags
|
||||||
self.use_dtb = use_dtb
|
self.use_dtb = use_dtb
|
||||||
return self.restart_uboot(expect_reset)
|
return self.restart_uboot(False)
|
||||||
finally:
|
finally:
|
||||||
self.sandbox_flags = []
|
self.sandbox_flags = []
|
||||||
self.use_dtb = True
|
self.use_dtb = True
|
||||||
|
|||||||
Reference in New Issue
Block a user