Compare commits

...

No commits in common. "c9-beta" and "c10s-add-release-automation" have entirely different histories.

18 changed files with 1351 additions and 130 deletions

View File

@ -1,2 +0,0 @@
41a56ab6bb51f99445735cf567ace0e9297fe8bc SOURCES/bootc-1.13.0-vendor.tar.zstd
46a80d31f9b5e715e75a5ff7d09a5663d48b0ab0 SOURCES/bootc-1.13.0.tar.zstd

1
.fmf/version Normal file
View File

@ -0,0 +1 @@
1

62
.gitignore vendored
View File

@ -1,2 +1,60 @@
SOURCES/bootc-1.13.0-vendor.tar.zstd
SOURCES/bootc-1.13.0.tar.zstd
/bootc-0.1.2.tar.zst
/bootc-0.1.2-vendor.tar.zst
/bootc-0.1.3-vendor.tar.zstd
/bootc-0.1.3.tar.zst
/bootc-0.1.4-vendor.tar.zstd
/bootc-0.1.4.tar.zstd
/bootc-0.1.5-vendor.tar.zstd
/bootc-0.1.5.tar.zstd
/bootc-0.1.6-vendor.tar.zstd
/bootc-0.1.6.tar.zstd
/bootc-0.1.12.tar.zstd
/bootc-0.1.12-vendor.tar.zstd
/bootc-0.1.13.tar.zstd
/bootc-0.1.13-vendor.tar.zstd
/bootc-0.1.14-vendor.tar.zstd
/bootc-0.1.14.tar.zstd
/bootc-0.1.15.tar.zstd
/bootc-0.1.15-vendor.tar.zstd
/bootc-0.1.16.tar.zstd
/bootc-0.1.16-vendor.tar.zstd
/bootc-1.1.0.tar.zstd
/bootc-1.1.0-vendor.tar.zstd
/bootc-1.1.2.tar.zstd
/bootc-1.1.2-vendor.tar.zstd
/bootc-1.1.3-vendor.tar.zstd
/bootc-1.1.3.tar.zstd
/bootc-1.1.4.tar.zstd
/bootc-1.1.4-vendor.tar.zstd
/bootc-1.1.5.tar.zstd
/bootc-1.1.5-vendor.tar.zstd
/bootc-1.1.6-vendor.tar.zstd
/bootc-1.1.6.tar.zstd
/bootc-1.1.7.tar.zstd
/bootc-1.1.7-vendor.tar.zstd
/bootc-1.3.0.tar.zstd
/bootc-1.3.0-vendor.tar.zstd
/bootc-1.4.0.tar.zstd
/bootc-1.4.0-vendor.tar.zstd
/bootc-1.5.1.tar.zstd
/bootc-1.5.1-vendor.tar.zstd
/bootc-1.7.0-vendor.tar.zstd
/bootc-1.7.0.tar.zstd
/bootc-1.7.1-vendor.tar.zstd
/bootc-1.7.1.tar.zstd
/bootc-1.8.0-vendor.tar.zstd
/bootc-1.8.0.tar.zstd
/bootc-1.10.0.tar.zstd
/bootc-1.10.0-vendor.tar.zstd
/bootc-1.11.0.tar.zstd
/bootc-1.11.0-vendor.tar.zstd
/bootc-1.12.0-vendor.tar.zstd
/bootc-1.12.0.tar.zstd
/bootc-1.12.1-vendor.tar.zstd
/bootc-1.12.1.tar.zstd
/bootc-1.15.1.tar.zstd
/bootc-1.15.1-vendor.tar.zstd
/bootc-1.15.2.tar.zstd
/bootc-1.15.2-vendor.tar.zstd
/bootc-1.16.2.tar.zstd
/bootc-1.16.2-vendor.tar.zstd

54
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,54 @@
---
# GitLab CI pipeline for automated bootc releases to CentOS Stream
# Runs every 6 hours to check for new upstream releases
workflow:
rules:
- when: always
stages:
- check
- release
# Check if there's a new upstream release
check_new_release:
stage: check
image: quay.io/centos/centos:stream10
before_script:
- dnf install -y git curl jq rpmdevtools
script:
- ./scripts/check-upstream-release.sh
artifacts:
reports:
dotenv: release.env
paths:
- release.env
expire_in: 1 hour
# Create MR if new release detected
create_release_mr:
stage: release
image: quay.io/centos/centos:stream10
before_script:
- dnf install -y git curl jq python3 rpmdevtools centpkg
# Configure git for bot
- git config --global user.name "bootc-release-bot"
- git config --global user.email "${BOT_EMAIL:-bootc-release-bot@redhat.com}"
# Set up SSH for centpkg (skip if TEST_MODE)
- |
if [[ "${TEST_MODE:-false}" != "true" ]]; then
mkdir -p ~/.ssh
echo "$CENTOS_SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -t rsa gitlab.com >> ~/.ssh/known_hosts
fi
script:
- ./scripts/create-release-mr.sh
rules:
- if: $TEST_MODE == "true"
- if: $NEW_RELEASE == "true"
needs:
- check_new_release
dependencies:
- check_new_release
# Test trigger

216
AUTOMATION-SETUP.md Normal file
View File

@ -0,0 +1,216 @@
# bootc CentOS Stream Automation - Setup Guide
This guide covers the steps needed to activate the automated release process.
## ✅ What's Been Created
The following automation infrastructure is ready:
- `.gitlab-ci.yml` - GitLab CI pipeline configuration
- `scripts/check-upstream-release.sh` - GitHub API poller
- `scripts/create-release-mr.sh` - Main automation orchestrator
- `scripts/update-spec.py` - Spec file updater
- `scripts/create-jira.sh` - JIRA API client
- `scripts/README.md` - Complete documentation
## 🧪 Testing the Workflow
Before setting up production automation, you can test locally:
```bash
# Test release detection and spec update (safe, no changes)
./scripts/test-workflow.sh
# Test in GitLab CI with TEST_MODE (stops before git push)
# 1. Push this branch to GitLab
# 2. Go to CI/CD → Pipelines → Run Pipeline
# 3. Add variable: TEST_MODE=true
# 4. Watch the pipeline execute and stop before making changes
```
**Note:** This automation is currently configured for **c10s only**. To enable for c9s:
1. Create a separate branch from c9s: `git checkout c9s && git checkout -b c9s-add-release-automation`
2. Merge or cherry-pick these changes
3. Update `.gitlab-ci.yml` to set `BASE_BRANCH: c9s`
4. Set up a separate scheduled pipeline for c9s
## 🔧 Required Setup Steps
### 1. Bot Account Creation
Create `bootc-release-bot` account (similar to imagebuilder-bot):
**GitLab Account:**
- Email: `bootc-release-bot@redhat.com`
- Add as Developer to: `gitlab.com/redhat/centos-stream/rpms/bootc`
**JIRA Account:**
- Same email: `bootc-release-bot@redhat.com`
- Request permissions to create issues in RHEL project
### 2. Generate Credentials
**GitLab API Token:**
1. Log in as bootc-release-bot
2. Go to User Settings → Access Tokens
3. Create token with scopes:
- `api`
- `write_repository`
4. Save the token securely
**GitLab SSH Key (for centpkg):**
```bash
ssh-keygen -t ed25519 -C "bootc-release-bot@redhat.com" -f ~/.ssh/bootc-bot
# Add public key to GitLab: Settings → SSH Keys
# Save private key for GitLab CI variable
```
**JIRA API Token:**
1. Log in to https://issues.redhat.com as bootc-release-bot
2. Go to Account Settings → Security → API Tokens
3. Create new token
4. Save the token securely
### 3. Configure GitLab CI/CD Variables
In the bootc GitLab project, go to **Settings → CI/CD → Variables** and add:
| Variable Name | Value | Type | Masked | Protected |
|---------------|-------|------|--------|-----------|
| `JIRA_API_TOKEN` | (JIRA token from step 2) | Variable | ✅ | ❌ |
| `GITLAB_API_TOKEN` | (GitLab token from step 2) | Variable | ✅ | ❌ |
| `CENTOS_SSH_PRIVATE_KEY` | (SSH private key from step 2) | File | ✅ | ❌ |
| `BOT_EMAIL` | `bootc-release-bot@redhat.com` | Variable | ❌ | ❌ |
| `ASSIGNEE_USER_ID` | (Your GitLab user ID) | Variable | ❌ | ❌ |
**To find your GitLab user ID:**
```bash
# Using GitLab API
curl "https://gitlab.com/api/v4/users?username=YOUR_USERNAME" | jq '.[0].id'
# Or check your profile URL: gitlab.com/YOUR_USERNAME
# The numeric ID is shown in the API response
```
### 4. Set Up Scheduled Pipeline
1. Go to **Settings → CI/CD → Schedules**
2. Click **New schedule**
3. Fill in:
- **Description:** `Check for new bootc releases`
- **Interval Pattern:** Custom
- **Cron:** `0 */6 * * *` (every 6 hours)
- **Cron timezone:** UTC
- **Target branch:** `c10s`
- **Active:**
4. Save schedule
### 5. Commit Automation to Repository
```bash
git add .gitlab-ci.yml scripts/
git commit -m "Add automated release pipeline
Implements weekly upstream rebase cadence automation:
- Polls GitHub every 6 hours for new releases
- Creates JIRA tickets automatically
- Updates spec file and creates MRs
- Leverages OSCI Bot for auto-merge
Resolves: #RHEL-XXXXX"
git push origin c9s
```
### 6. Test the Automation
**Dry Run Test:**
1. Go to **CI/CD → Pipelines**
2. Click **Run pipeline**
3. Select branch: `c10s`
4. Click **Run pipeline**
5. Watch the pipeline execute
6. Verify it detects the current version correctly
**Live Test (when next release happens):**
1. Wait for next upstream bootc release
2. Within 6 hours, check for automated MR
3. Verify MR has:
- Correct version in title and spec
- JIRA ticket created and referenced
- Assignee set for notifications
4. Monitor OSCI Bot checks
5. Confirm auto-merge if tests pass
## 📋 Checklist
Before going live, ensure:
- [ ] `bootc-release-bot` account created
- [ ] Bot added as Developer to GitLab project
- [ ] Bot has JIRA issue creation permissions
- [ ] GitLab API token generated
- [ ] SSH key generated and added
- [ ] JIRA API token generated
- [ ] All 5 CI/CD variables configured
- [ ] Scheduled pipeline created
- [ ] Automation code committed to `c9s`
- [ ] Dry run pipeline executed successfully
- [ ] Team notified about new automation
## 🎯 Expected Behavior
Once active:
1. **Every 6 hours:** Pipeline checks for new releases
2. **When new release found:**
- JIRA ticket created automatically
- Tarballs downloaded from GitHub
- Spec file updated with changelog
- MR created and assigned
3. **OSCI Bot workflow:**
- Runs all required tests
- Auto-approves if tests pass
- Auto-merges with Red Hat approval
4. **If tests fail:**
- Assignee gets email notification
- Manual intervention required
## 🆘 Rollback Plan
If automation causes issues:
1. **Disable schedule:**
- Go to Settings → CI/CD → Schedules
- Toggle schedule to inactive
2. **Revert code:**
```bash
git revert <commit-hash>
git push origin c9s
```
3. **Return to manual process** (documented in scripts/README.md)
## 📞 Support Contacts
- GitLab permissions: (Your GitLab admin contact)
- JIRA permissions: (Your JIRA admin contact)
- Bot account setup: (Your IT/identity management contact)
## 🔍 Monitoring
Track automation health:
- **Pipeline success rate:** Settings → CI/CD → Pipelines
- **MR auto-merge rate:** Check recent MRs for OSCI Bot approvals
- **Missed releases:** Compare GitHub releases vs CentOS Stream versions weekly
Target metrics:
- Pipeline success rate: >95%
- Auto-merge rate: >90%
- Release detection latency: <6 hours
---
**Questions or issues?** See `scripts/README.md` for troubleshooting guide.

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# bootc
The bootc package

View File

@ -22,8 +22,8 @@
%endif
Name: bootc
Version: 1.13.0
Release: 1%{?dist}
Version: 1.16.2
Release: %{autorelease}
Summary: Bootable container system
# Apache-2.0
@ -213,127 +213,4 @@ fi
%endif
%changelog
* Mon Feb 24 2026 Colin Walters <walters@verbum.org> - 1.13.0-1
- Update to 1.13.0
- https://github.com/bootc-dev/bootc/releases/tag/v1.13.0
- Resolves: RHEL-151443
* Fri Jan 17 2026 Colin Walters <walters@verbum.org> - 1.12.1-1
- Update to 1.12.1
- Fix mount point check regression breaking bootc-image-builder
- Resolves: RHEL-142112
* Thu Jan 09 2026 Colin Walters <walters@verbum.org> - 1.12.0-1
- Update to 1.12.0
- Resolves: RHEL-140335
* Thu Oct 30 2025 Joseph Marrero <jmarrero@fedoraproject.org> - 1.10.0-1
- Update to 1.10.0
- Resolves: #RHEL-125340
* Fri Sep 05 2025 Colin Walters <walters@verbum.org> - 1.8.0-2
- Update to 1.8.0
* Tue Aug 26 2025 Joseph Marrero <jmarrero@fedoraproject.org> - 1.7.1-1
- Update to 1.7.1
- Resolves: #RHEL-111339
* Thu Aug 21 2025 Joseph Marrero <jmarrero@fedoraproject.org> - 1.7.0-1
- Update to 1.7.0
- Resolves: #RHEL-109555
* Fri Jul 22 2025 Gursewak Mangat <gurssing@redhat.com> - 1.5.1-1
- Update to 1.5.1
- Resolves: #RHEL-104335
* Fri Jul 11 2025 Gursewak Mangat <gurssing@redhat.com> - 1.4.0-1
- Update to 1.4.0
- Resolves: #RHEL-103125
* Fri May 30 2025 Joseph Marrero <jmarrero@fedoraproject.org> - 1.3.0-1
- Update to 1.3.0
- Resolves: #RHEL-94597
* Tue Apr 15 2025 John Eckersberg <jeckersb@redhat.com> - 1.1.7-1
- Update to 1.1.7
- Resolves: #RHEL-87207
* Thu Mar 06 2025 Joseph Marrero <jmarrero@fedoraproject.org> - 1.1.6-3
- Backport https://github.com/containers/bootc/pull/1167
- Resolves: #RHEL-82293
* Wed Feb 19 2025 John Eckersberg <jeckersb@redhat.com> - 1.1.5-2
- Sync specfile from upstream
- Resolves: #RHEL-80264
- Resolves: #RHEL-81981
* Mon Feb 10 2025 Joseph Marrero <jmarrero@fedoraproject.org> - 1.1.5-1
- Update to 1.1.5
- Resolves: #RHEL-77733
* Thu Jan 23 2025 John Eckersberg <jeckersb@redhat.com> - 1.1.4-2
- Cherry pick patches for bootc-status-updated
- Resolves: #RHEL-72862
* Tue Jan 14 2025 Joseph Marrero <jmarrero@fedoraproject.org> - 1.1.4-1
- Update to 1.1.4
Resolves: #RHEL-72862
* Thu Nov 07 2024 Joseph Marrero <jmarrero@fedoraproject.org> - 1.1.2-1
- Update to 1.1.2
Resolves: #RHEL-66258
* Thu Oct 17 2024 Joseph Marrero <jmarrero@fedoraproject.org> - 1.1.0-1
- Update to 1.1.0
Resolves: #RHEL-63018
* Fri Aug 16 2024 Colin Walters <walters@verbum.org> - 0.1.15-1
- Update to 0.1.15
Resolves: #RHEL-50625
* Thu Jul 25 2024 Joseph Marrero <jmarrero@fedoraproject.org> - 0.1.14-1
- Update to 0.1.14
Resolves: #RHEL-50625, #RHEL-45325, #RHEL-36003
* Fri Jun 28 2024 Colin Walters <walters@verbum.org> - 0.1.13-2
- Update to 0.1.13
* Tue Jun 25 2024 Colin Walters <walters@verbum.org> - 0.1.12-3
- Update to 0.1.12
* Wed May 15 2024 Colin Walters <walters@verbum.org> - 0.1.11-2
- Update to 0.1.11
* Fri Apr 26 2024 Colin Walters <walters@verbum.org> - 0.1.10-2
- Release 0.1.10
* Mon Apr 08 2024 Colin Walters <walters@verbum.org> - 0.1.9-4
- Correct JIRA link
Resolves: #RHEL-30878
* Thu Mar 28 2024 Colin Walters <walters@verbum.org> - 0.1.9-3
- Backport rollback
Related: #RHEL-30466
* Wed Mar 27 2024 Colin Walters <walters@verbum.org> - 0.1.9-2
- https://github.com/containers/bootc/releases/tag/v0.1.9
Resolves: #RHEL-30466
* Tue Mar 19 2024 Colin Walters <walters@verbum.org> - 0.1.8-2
- https://github.com/containers/bootc/releases/tag/v0.1.8
* Wed Feb 14 2024 Colin Walters <walters@verbum.org> - 0.1.7-4
- https://github.com/containers/bootc/releases/tag/v0.1.7
* Tue Jan 23 2024 Colin Walters <walters@verbum.org> - 0.1.6-2
- https://github.com/containers/bootc/releases/tag/v0.1.6
* Fri Jan 12 2024 Joseph Marrero <jmarrero@redhat.com> - 0.1.5-1
- Update to https://github.com/containers/bootc/releases/tag/v0.1.5
* Thu Jan 11 2024 Colin Walters <walters@verbum.org> - 0.1.4-3
- Loosen composefs requirement until it makes it into c9s
* Mon Dec 11 2023 Colin Walters <walters@verbum.org> - 0.1.4-2
- Initial import from fedora
%autochangelog

17
gating.yaml Normal file
View File

@ -0,0 +1,17 @@
--- !Policy
product_versions:
- fedora-*
decision_contexts:
- bodhi_update_push_stable
- bodhi_update_push_testing
subject_type: koji_build
rules:
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build.tier0.functional}
--- !Policy
product_versions:
- rhel-9
- rhel-10
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}

20
os-image-map.json Normal file
View File

@ -0,0 +1,20 @@
{
"base": {
"rhel-10.3": "images.paas.redhat.com/bootc/rhel-bootc:latest-10.3",
"rhel-10.2": "images.paas.redhat.com/bootc/rhel-bootc:latest-10.2",
"rhel-9.9": "images.paas.redhat.com/bootc/rhel-bootc:latest-9.9",
"rhel-9.8": "images.paas.redhat.com/bootc/rhel-bootc:latest-9.8",
"centos-9": "quay.io/centos-bootc/centos-bootc:stream9",
"centos-10": "quay.io/centos-bootc/centos-bootc:stream10",
"fedora-42": "quay.io/fedora/fedora-bootc:42",
"fedora-43": "quay.io/fedora/fedora-bootc:43",
"fedora-44": "quay.io/fedora/fedora-bootc:rawhide"
},
"buildroot-base": {
"centos-9": "quay.io/centos/centos:stream9",
"centos-10": "quay.io/centos/centos:stream10",
"fedora-42": "quay.io/fedora/fedora:42",
"fedora-43": "quay.io/fedora/fedora:43",
"fedora-44": "quay.io/fedora/fedora:rawhide"
}
}

100
plans/all.fmf Normal file
View File

@ -0,0 +1,100 @@
discover:
how: fmf
dist-git-source: true
dist-git-install-builddeps: true
execute:
how: tmt
environment:
NIGHTLY_COMPOSE_SITE: download.devel.redhat.com
prepare:
# Install image mode system on package mode system
- how: install
order: 97
package:
- podman
- skopeo
- jq
- bootc
- system-reinstall-bootc
- expect
- ansible-core
- zstd
- how: shell
order: 98
script:
- pwd && ls -al && ls -al /var/share/test-artifacts && mkdir -p bootc && cp /var/share/test-artifacts/*.src.rpm bootc
- cd bootc && ls -al && rpm2cpio *.src.rpm | cpio -idmv && rm -f *-vendor.tar.zstd && zstd -d *.tar.zstd && tar -xvf *.tar -C . --strip-components=1 && ls -al
# Remove the "cp" line in next release, the fix already added in bootc upstream
- cp os-image-map.json bootc/hack
- cd bootc/hack && ./provision-packit.sh
# tmt-reboot and reboot do not work in this case
# reboot in ansible is the only way to reboot in tmt prepare
- how: ansible
order: 99
playbook:
- https://github.com/bootc-dev/bootc/raw/refs/heads/main/hack/packit-reboot.yml
/plan-01-readonly:
summary: Execute booted readonly/nondestructive tests
discover+:
how: fmf
test:
- /tmt/tests/tests/test-01-readonly
extra-try_bind_storage: true
/plan-20-image-pushpull-upgrade:
summary: Execute local upgrade tests
discover+:
how: fmf
test:
- /tmt/tests/tests/test-20-image-pushpull-upgrade
/plan-21-logically-bound-switch:
summary: Execute logically bound images tests for switching images
discover+:
how: fmf
test:
- /tmt/tests/tests/test-21-logically-bound-switch
/plan-22-logically-bound-install:
summary: Execute logically bound images tests for installing image
discover+:
how: fmf
test:
- /tmt/tests/tests/test-22-logically-bound-install
/plan-23-install-outside-container:
summary: Execute tests for installing outside of a container
discover+:
how: fmf
test:
- /tmt/tests/tests/test-23-install-outside-container
/plan-23-usroverlay:
summary: Execute tests for bootc usrover
discover+:
how: fmf
test:
- /tmt/tests/tests/test-23-usroverlay
/plan-24-image-upgrade-reboot:
summary: Execute local upgrade tests
discover+:
how: fmf
test:
- /tmt/tests/tests/test-24-image-upgrade-reboot
extra-try_bind_storage: true
/plan-25-soft-reboot:
summary: Execute soft reboot test
discover+:
how: fmf
test:
- /tmt/tests/tests/test-25-soft-reboot
/plan-29-soft-reboot-selinux-policy:
summary: Test soft reboot with SELinux policy changes
discover+:
how: fmf
test:
- /tmt/tests/tests/test-29-soft-reboot-selinux-policy

4
rpminspect.yaml Normal file
View File

@ -0,0 +1,4 @@
# Disable the symlink check for the problematic path
symlinks:
ignore:
- /usr/lib/bootc/storage

242
scripts/README.md Normal file
View File

@ -0,0 +1,242 @@
# bootc CentOS Stream Release Automation
This directory contains scripts for automating bootc releases to CentOS Stream.
## Overview
The automation runs as a GitLab CI scheduled pipeline (every 6 hours) that:
1. Checks GitHub for new bootc releases
2. Creates a JIRA ticket for tracking
3. Downloads tarballs from GitHub
4. Updates the spec file and sources
5. Creates a GitLab Merge Request
6. OSCI Bot handles CI checks and auto-merges if all tests pass
## Architecture
```
┌─────────────────────────────────────────────┐
│ GitLab Scheduled Pipeline (every 6 hours) │
└──────────────┬──────────────────────────────┘
┌─────────────────────────────────────────────┐
│ check_new_release job │
│ → scripts/check-upstream-release.sh │
│ → Compares GitHub latest vs spec version │
│ → Outputs: release.env │
└──────────────┬──────────────────────────────┘
│ if NEW_RELEASE=true
┌─────────────────────────────────────────────┐
│ create_release_mr job │
│ → scripts/create-release-mr.sh │
│ ├─ Download tarballs from GitHub │
│ ├─ Create JIRA (scripts/create-jira.sh) │
│ ├─ Upload sources via centpkg │
│ ├─ Update spec (scripts/update-spec.py) │
│ ├─ Commit and push branch │
│ └─ Create GitLab MR via API │
└──────────────┬──────────────────────────────┘
┌─────────────────────────────────────────────┐
│ OSCI Bot Workflow (automatic) │
│ → Runs required checks │
│ → Auto-approves if tests pass │
│ → Auto-merges with Red Hat approval │
└─────────────────────────────────────────────┘
```
## Scripts
### `check-upstream-release.sh`
Polls the GitHub API for the latest bootc release and compares it with the current spec file version.
**Usage:**
```bash
./scripts/check-upstream-release.sh
```
**Output:**
Creates `release.env` with:
- `NEW_RELEASE` (true/false)
- `VERSION` (e.g., "1.5.2")
- `RELEASE_TAG` (e.g., "v1.5.2")
- `CURRENT_VERSION` (current spec version)
### `create-release-mr.sh`
Main automation script that orchestrates the entire release process.
**Prerequisites:**
- `release.env` must exist (created by check-upstream-release.sh)
- Environment variables configured (see below)
- `centpkg` installed and configured
- Git credentials set up
**What it does:**
1. Downloads tarballs from GitHub releases
2. Creates JIRA ticket via API
3. Creates working branch (`rebase-X.Y.Z`)
4. Uploads sources to CentOS lookaside cache
5. Updates spec file (Version, Release, changelog)
6. Commits and pushes changes
7. Creates GitLab MR with assignee
**Usage:**
```bash
# Normally run by GitLab CI, but can be run manually:
export VERSION=1.5.2
export RELEASE_TAG=v1.5.2
./scripts/create-release-mr.sh
```
### `update-spec.py`
Python helper to safely update the spec file.
**Usage:**
```bash
./scripts/update-spec.py <spec_file> <version> <jira_ticket> [author]
```
**Example:**
```bash
./scripts/update-spec.py bootc.spec 1.5.2 RHEL-104567
```
**What it does:**
- Updates `Version:` field
- Resets `Release:` to `1%{?dist}`
- Adds properly formatted changelog entry
- Preserves spec file formatting
### `create-jira.sh`
Creates a JIRA issue for the release via REST API.
**Usage:**
```bash
export JIRA_API_TOKEN="your-token-here"
./scripts/create-jira.sh <version> [upstream_url]
```
**Example:**
```bash
./scripts/create-jira.sh 1.5.2
# Outputs: RHEL-104567
```
**Returns:** JIRA ticket key (e.g., `RHEL-104567`) on stdout
## GitLab CI/CD Variables
Configure these in **Settings → CI/CD → Variables**:
| Variable | Description | Type |
|----------|-------------|------|
| `JIRA_API_TOKEN` | JIRA API token for bootc-release-bot | Masked |
| `GITLAB_API_TOKEN` | GitLab API token (scope: `api`, `write_repository`) | Masked |
| `CENTOS_SSH_PRIVATE_KEY` | SSH private key for centpkg lookaside uploads | File, Masked |
| `BOT_EMAIL` | bootc-release-bot@redhat.com | Variable |
| `ASSIGNEE_USER_ID` | GitLab user ID for MR assignee (e.g., `1234567`) | Variable |
## GitLab Schedule Setup
1. Go to **Settings → CI/CD → Schedules**
2. Click **New schedule**
3. Configure:
- **Description:** "Check for new bootc releases"
- **Interval:** Custom → `0 */6 * * *` (every 6 hours)
- **Target branch:** `c10s`
- **Active:** ✅ Yes
## Manual Testing
### Test the release checker
```bash
./scripts/check-upstream-release.sh
cat release.env
```
### Test spec file update
```bash
./scripts/update-spec.py bootc.spec 1.5.2 RHEL-TEST-001 "Your Name <your@email.com>"
git diff bootc.spec
git restore bootc.spec # Undo changes
```
### Test JIRA creation (requires API token)
```bash
export JIRA_API_TOKEN="your-token"
./scripts/create-jira.sh 1.5.2
```
### Trigger pipeline manually
1. Go to **CI/CD → Pipelines**
2. Click **Run pipeline**
3. Select branch: `c10s`
4. Add variable: `CI_PIPELINE_SOURCE` = `web`
5. Click **Run pipeline**
## Troubleshooting
### Pipeline fails at check_new_release
- Verify GitHub API is accessible: `curl -s https://api.github.com/repos/containers/bootc/releases/latest | jq .tag_name`
- Check spec file exists and is parseable: `rpmspec -q --queryformat='%{version}\n' bootc.spec`
### Pipeline fails at create_release_mr
- **JIRA creation fails:** Check `JIRA_API_TOKEN` is valid and bot has permissions
- The automation continues with placeholder `RHEL-XXXXX` if JIRA fails
- **centpkg upload fails:** Check `CENTOS_SSH_PRIVATE_KEY` is configured correctly
- **Git push fails:** Verify bot has Developer role on the GitLab project
- **MR creation fails:** Check `GITLAB_API_TOKEN` has `api` and `write_repository` scopes
### MR created but not auto-merging
- Check OSCI Bot comments on the MR for test failures
- Ensure another Red Hatter approves the MR (required for auto-merge)
- Review failed tests and fix issues
### No new releases detected
- Verify upstream has actually released a new version: https://github.com/containers/bootc/releases
- Check current spec version matches latest upstream: `rpmspec -q --queryformat='%{version}\n' bootc.spec`
## Bot Account Setup
The automation uses `bootc-release-bot` account:
**GitLab:**
- Developer role on `gitlab.com/redhat/centos-stream/rpms/bootc`
- API token with `api` and `write_repository` scopes
- SSH key for centpkg uploads
**JIRA:**
- Account with issue creation permissions in RHEL project
- API token configured in GitLab CI/CD variables
**Git config:**
```bash
git config user.name "bootc-release-bot"
git config user.email "bootc-release-bot@redhat.com"
```
## Weekly Cadence
With the 6-hour scheduled pipeline, new releases are detected within:
- **Best case:** <6 hours after upstream release
- **Average:** 3 hours after upstream release
- **Worst case:** ~6 hours after upstream release
This ensures the weekly cadence is maintained with minimal manual intervention.
## Success Metrics
- ✅ Zero missed upstream releases
- ✅ MRs created within 6 hours of upstream release
- ✅ Auto-merge rate >90% (indicates healthy CI)
- ✅ Manual intervention required <10% of releases
## Support
For issues or questions:
- Check GitLab pipeline logs for detailed error messages
- Review OSCI Bot comments on MRs for test failures
- Contact the bootc team for bot account or permission issues

View File

@ -0,0 +1,65 @@
#!/bin/bash
# Check for new bootc releases on GitHub
# Outputs release.env file with NEW_RELEASE, VERSION, and RELEASE_TAG variables
set -euo pipefail
readonly GITHUB_API="https://api.github.com/repos/containers/bootc/releases/latest"
readonly SPEC_FILE="bootc.spec"
log_info() {
echo "[INFO] $*"
}
log_error() {
echo "[ERROR] $*" >&2
}
# Fetch latest release from GitHub
log_info "Fetching latest release from GitHub..."
LATEST_RELEASE=$(curl -sL "$GITHUB_API" | jq -r '.tag_name')
if [[ -z "$LATEST_RELEASE" ]] || [[ "$LATEST_RELEASE" == "null" ]]; then
log_error "Failed to fetch latest release from GitHub"
exit 1
fi
# Strip 'v' prefix from tag (e.g., v1.5.2 -> 1.5.2)
LATEST_VERSION="${LATEST_RELEASE#v}"
log_info "Latest upstream release: $LATEST_VERSION ($LATEST_RELEASE)"
# Get current version from spec file
if [[ ! -f "$SPEC_FILE" ]]; then
log_error "Spec file not found: $SPEC_FILE"
exit 1
fi
CURRENT_VERSION=$(rpmspec -q --queryformat='%{version}\n' "$SPEC_FILE" 2>/dev/null | head -1)
if [[ -z "$CURRENT_VERSION" ]]; then
log_error "Failed to parse version from spec file"
exit 1
fi
log_info "Current spec version: $CURRENT_VERSION"
# Compare versions
if [[ "$LATEST_VERSION" != "$CURRENT_VERSION" ]]; then
log_info "New release detected: $CURRENT_VERSION -> $LATEST_VERSION"
cat > release.env <<EOF
NEW_RELEASE=true
VERSION=$LATEST_VERSION
RELEASE_TAG=$LATEST_RELEASE
CURRENT_VERSION=$CURRENT_VERSION
EOF
else
log_info "No new release (current: $CURRENT_VERSION)"
cat > release.env <<EOF
NEW_RELEASE=false
VERSION=$CURRENT_VERSION
RELEASE_TAG=$LATEST_RELEASE
CURRENT_VERSION=$CURRENT_VERSION
EOF
fi
cat release.env

102
scripts/create-jira.sh Executable file
View File

@ -0,0 +1,102 @@
#!/bin/bash
# Create JIRA issue for bootc release
# Returns JIRA ticket key (e.g., RHEL-104567) on success
set -euo pipefail
VERSION="${1:-}"
UPSTREAM_URL="${2:-}"
if [[ -z "$VERSION" ]]; then
echo "Usage: $0 <version> [upstream_url]" >&2
exit 1
fi
if [[ -z "$UPSTREAM_URL" ]]; then
UPSTREAM_URL="https://github.com/containers/bootc/releases/tag/v${VERSION}"
fi
log_info() {
echo "[JIRA] $*"
}
log_error() {
echo "[JIRA ERROR] $*" >&2
}
# Check for required env vars
if [[ -z "${JIRA_API_TOKEN:-}" ]]; then
log_error "JIRA_API_TOKEN environment variable not set"
exit 1
fi
# JIRA API endpoint (v3 as per Red Hat Jira)
JIRA_API="https://issues.redhat.com/rest/api/3/issue"
# Create payload
SUMMARY="Update bootc to ${VERSION} in CentOS Stream"
DESCRIPTION="Automated release update from upstream bootc v${VERSION}
Upstream release: ${UPSTREAM_URL}
This issue was created automatically by bootc-release-bot."
PAYLOAD=$(cat <<EOF
{
"fields": {
"project": {
"key": "RHEL"
},
"summary": "$SUMMARY",
"description": {
"type": "doc",
"version": 1,
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "$DESCRIPTION"
}
]
}
]
},
"issuetype": {
"name": "Story"
}
}
}
EOF
)
log_info "Creating JIRA issue: $SUMMARY"
# Make API call
RESPONSE=$(curl -s -w "\n%{http_code}" \
-X POST \
-H "Authorization: Bearer ${JIRA_API_TOKEN}" \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
"$JIRA_API")
HTTP_CODE=$(echo "$RESPONSE" | tail -n 1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [[ "$HTTP_CODE" -ge 200 ]] && [[ "$HTTP_CODE" -lt 300 ]]; then
JIRA_KEY=$(echo "$BODY" | jq -r '.key')
if [[ -n "$JIRA_KEY" ]] && [[ "$JIRA_KEY" != "null" ]]; then
log_info "Successfully created: $JIRA_KEY"
echo "$JIRA_KEY"
exit 0
else
log_error "Failed to parse JIRA key from response"
echo "$BODY" >&2
exit 1
fi
else
log_error "API request failed with HTTP $HTTP_CODE"
echo "$BODY" >&2
exit 1
fi

234
scripts/create-release-mr.sh Executable file
View File

@ -0,0 +1,234 @@
#!/bin/bash
# Main automation script for creating CentOS Stream bootc release MRs
# Expects VERSION and RELEASE_TAG from release.env
set -euo pipefail
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
readonly SPEC_FILE="$REPO_ROOT/bootc.spec"
readonly GITHUB_REPO="containers/bootc"
readonly BASE_BRANCH="${BASE_BRANCH:-c10s}"
readonly GITLAB_PROJECT_ID="redhat/centos-stream/rpms/bootc"
readonly TEST_MODE="${TEST_MODE:-false}"
log_info() {
echo "[INFO] $*"
}
log_warn() {
echo "[WARN] $*" >&2
}
log_error() {
echo "[ERROR] $*" >&2
}
die() {
log_error "$*"
exit 1
}
# Source release.env from check stage
if [[ -f "$REPO_ROOT/release.env" ]]; then
source "$REPO_ROOT/release.env"
else
die "release.env not found"
fi
[[ -z "${VERSION:-}" ]] && die "VERSION not set in release.env"
[[ -z "${RELEASE_TAG:-}" ]] && die "RELEASE_TAG not set in release.env"
log_info "Starting release automation for bootc ${VERSION}"
log_info "Release tag: ${RELEASE_TAG}"
if [[ "$TEST_MODE" == "true" ]]; then
log_warn "⚠️ TEST MODE ENABLED - Will stop before making actual changes"
fi
cd "$REPO_ROOT"
# Step 1: Download tarballs from GitHub
log_info "Downloading tarballs from GitHub..."
TARBALL_MAIN="bootc-${VERSION}.tar.zstd"
TARBALL_VENDOR="bootc-${VERSION}-vendor.tar.zstd"
DOWNLOAD_URL="https://github.com/${GITHUB_REPO}/releases/download/${RELEASE_TAG}"
mkdir -p /tmp/bootc-release
cd /tmp/bootc-release
if ! curl -L -f -o "$TARBALL_MAIN" "${DOWNLOAD_URL}/${TARBALL_MAIN}"; then
die "Failed to download $TARBALL_MAIN"
fi
if ! curl -L -f -o "$TARBALL_VENDOR" "${DOWNLOAD_URL}/${TARBALL_VENDOR}"; then
die "Failed to download $TARBALL_VENDOR"
fi
log_info "Downloaded tarballs successfully"
ls -lh "$TARBALL_MAIN" "$TARBALL_VENDOR"
# Step 2: Create JIRA issue
log_info "Creating JIRA issue..."
JIRA_TICKET=""
if JIRA_TICKET=$("$SCRIPT_DIR/create-jira.sh" "$VERSION" "${DOWNLOAD_URL}"); then
log_info "Created JIRA ticket: $JIRA_TICKET"
else
log_warn "Failed to create JIRA ticket (will use placeholder)"
JIRA_TICKET="RHEL-XXXXX"
fi
# Step 3: Set up git repository
cd "$REPO_ROOT"
log_info "Setting up git repository..."
# Fetch latest
git fetch origin "$BASE_BRANCH"
git checkout "$BASE_BRANCH"
git pull origin "$BASE_BRANCH"
# Create working branch
WORK_BRANCH="rebase-${VERSION}"
log_info "Creating branch: $WORK_BRANCH"
if git show-ref --verify --quiet "refs/heads/$WORK_BRANCH"; then
log_warn "Branch $WORK_BRANCH already exists, deleting..."
git branch -D "$WORK_BRANCH"
fi
git checkout -b "$WORK_BRANCH"
# Step 4: Upload sources to lookaside cache
if [[ "$TEST_MODE" == "true" ]]; then
log_warn "[TEST MODE] Skipping centpkg upload"
else
log_info "Uploading sources to lookaside cache..."
if ! centpkg new-sources "/tmp/bootc-release/$TARBALL_MAIN" "/tmp/bootc-release/$TARBALL_VENDOR"; then
die "Failed to upload sources"
fi
log_info "Sources uploaded successfully"
git diff sources .gitignore
fi
# Step 5: Update spec file
log_info "Updating spec file..."
if ! "$SCRIPT_DIR/update-spec.py" "$SPEC_FILE" "$VERSION" "$JIRA_TICKET"; then
die "Failed to update spec file"
fi
# Step 6: Verify spec file
log_info "Verifying spec file syntax..."
if ! rpmspec --parse "$SPEC_FILE" > /dev/null 2>&1; then
die "Spec file has syntax errors"
fi
# Step 7: Commit changes
if [[ "$TEST_MODE" == "true" ]]; then
log_warn "[TEST MODE] Would commit changes with message:"
echo "---"
echo "spec: new upstream version ${VERSION}"
if [[ "$JIRA_TICKET" != "RHEL-XXXXX" ]]; then
echo ""
echo "Resolves: ${JIRA_TICKET}"
fi
echo "---"
log_info "Changes that would be committed:"
git diff "$SPEC_FILE"
log_warn "[TEST MODE] Stopping here - no actual git push or MR creation"
log_info "Test completed successfully! 🎉"
exit 0
fi
log_info "Committing changes..."
git add sources .gitignore "$SPEC_FILE"
COMMIT_MSG="spec: new upstream version ${VERSION}"
if [[ "$JIRA_TICKET" != "RHEL-XXXXX" ]]; then
COMMIT_MSG="${COMMIT_MSG}
Resolves: ${JIRA_TICKET}"
fi
git commit -m "$COMMIT_MSG"
log_info "Commit created:"
git log -1 --oneline
# Step 8: Push branch
log_info "Pushing branch to origin..."
if ! git push origin "$WORK_BRANCH"; then
die "Failed to push branch"
fi
log_info "Branch pushed successfully"
# Step 9: Create GitLab MR
log_info "Creating GitLab Merge Request..."
MR_TITLE="spec: new upstream version ${VERSION}"
MR_DESCRIPTION="Automated release update from upstream bootc ${RELEASE_TAG}
**Changes:**
- Update Version to ${VERSION}
- Reset Release to 1%{?dist}
- Add changelog entry
**Upstream release:** ${DOWNLOAD_URL}
**JIRA:** ${JIRA_TICKET}
---
_This MR was created automatically by bootc-release-bot._"
# URL-encode the project ID
PROJECT_ID_ENCODED=$(echo "$GITLAB_PROJECT_ID" | sed 's|/|%2F|g')
MR_PAYLOAD=$(cat <<EOF
{
"source_branch": "$WORK_BRANCH",
"target_branch": "$BASE_BRANCH",
"title": "$MR_TITLE",
"description": $(echo "$MR_DESCRIPTION" | jq -Rs .),
"remove_source_branch": true
}
EOF
)
# Add assignee if configured
if [[ -n "${ASSIGNEE_USER_ID:-}" ]]; then
MR_PAYLOAD=$(echo "$MR_PAYLOAD" | jq --argjson id "$ASSIGNEE_USER_ID" '. + {assignee_ids: [$id]}')
fi
GITLAB_API="https://gitlab.com/api/v4/projects/${PROJECT_ID_ENCODED}/merge_requests"
MR_RESPONSE=$(curl -s -w "\n%{http_code}" \
-X POST \
-H "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \
-H "Content-Type: application/json" \
-d "$MR_PAYLOAD" \
"$GITLAB_API")
HTTP_CODE=$(echo "$MR_RESPONSE" | tail -n 1)
BODY=$(echo "$MR_RESPONSE" | sed '$d')
if [[ "$HTTP_CODE" -ge 200 ]] && [[ "$HTTP_CODE" -lt 300 ]]; then
MR_URL=$(echo "$BODY" | jq -r '.web_url')
MR_IID=$(echo "$BODY" | jq -r '.iid')
log_info "✅ Merge Request created successfully!"
echo
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 Release: bootc ${VERSION}"
echo "🎫 JIRA: ${JIRA_TICKET}"
echo "🔀 MR !${MR_IID}: ${MR_URL}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo
echo "Next: OSCI Bot will run checks and auto-merge if all tests pass."
else
log_error "Failed to create MR (HTTP $HTTP_CODE)"
echo "$BODY" >&2
exit 1
fi
# Cleanup
rm -rf /tmp/bootc-release
log_info "Release automation complete!"

142
scripts/test-workflow.sh Executable file
View File

@ -0,0 +1,142 @@
#!/bin/bash
# Test the release automation workflow locally (dry-run mode)
# This script simulates what the GitLab CI pipeline does without making actual changes
set -euo pipefail
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
echo "========================================="
echo "bootc Release Automation - Test Mode"
echo "========================================="
echo
cd "$REPO_ROOT"
# Step 1: Test release checker
echo "📡 Step 1: Checking for new releases..."
echo "----------------------------------------"
if ! "$SCRIPT_DIR/check-upstream-release.sh"; then
echo "❌ Failed to check releases"
exit 1
fi
echo
echo "📄 Release info:"
cat release.env
echo
source release.env
if [[ "$NEW_RELEASE" != "true" ]]; then
echo "✅ No new release detected"
echo "Current version: $CURRENT_VERSION"
echo "Latest upstream: $VERSION"
echo
echo "To test with a fake version, modify check-upstream-release.sh temporarily."
exit 0
fi
echo "🆕 New release detected: $VERSION"
echo
# Step 2: Test JIRA creation (optional, requires token)
echo "🎫 Step 2: Testing JIRA creation (optional)..."
echo "----------------------------------------"
if [[ -n "${JIRA_API_TOKEN:-}" ]]; then
echo "JIRA_API_TOKEN is set, testing creation..."
if JIRA_TICKET=$("$SCRIPT_DIR/create-jira.sh" "$VERSION"); then
echo "✅ JIRA ticket created: $JIRA_TICKET"
echo
echo "⚠️ WARNING: This created a REAL JIRA ticket!"
echo "You may want to close/delete it: https://issues.redhat.com/browse/$JIRA_TICKET"
else
echo "❌ JIRA creation failed (this is OK for testing)"
JIRA_TICKET="RHEL-TEST-001"
fi
else
echo "⏭️ Skipping JIRA creation (JIRA_API_TOKEN not set)"
JIRA_TICKET="RHEL-TEST-001"
fi
echo
# Step 3: Test spec file update (in a temporary copy)
echo "📝 Step 3: Testing spec file update..."
echo "----------------------------------------"
TEMP_SPEC=$(mktemp)
cp bootc.spec "$TEMP_SPEC"
if "$SCRIPT_DIR/update-spec.py" "$TEMP_SPEC" "$VERSION" "$JIRA_TICKET" "Test Bot <test@example.com>"; then
echo "✅ Spec file updated successfully"
echo
echo "Diff preview:"
diff -u bootc.spec "$TEMP_SPEC" || true
echo
else
echo "❌ Failed to update spec file"
rm -f "$TEMP_SPEC"
exit 1
fi
# Verify spec syntax
if rpmspec --parse "$TEMP_SPEC" > /dev/null 2>&1; then
echo "✅ Spec file syntax is valid"
else
echo "❌ Spec file has syntax errors"
rm -f "$TEMP_SPEC"
exit 1
fi
rm -f "$TEMP_SPEC"
echo
# Step 4: Simulate tarball download
echo "📦 Step 4: Checking tarball availability..."
echo "----------------------------------------"
DOWNLOAD_URL="https://github.com/containers/bootc/releases/download/${RELEASE_TAG}"
TARBALL_MAIN="bootc-${VERSION}.tar.zstd"
TARBALL_VENDOR="bootc-${VERSION}-vendor.tar.zstd"
if curl -I -s -f "${DOWNLOAD_URL}/${TARBALL_MAIN}" > /dev/null; then
echo "✅ Main tarball exists: ${TARBALL_MAIN}"
else
echo "❌ Main tarball not found: ${DOWNLOAD_URL}/${TARBALL_MAIN}"
fi
if curl -I -s -f "${DOWNLOAD_URL}/${TARBALL_VENDOR}" > /dev/null; then
echo "✅ Vendor tarball exists: ${TARBALL_VENDOR}"
else
echo "❌ Vendor tarball not found: ${DOWNLOAD_URL}/${TARBALL_VENDOR}"
fi
echo
# Summary
echo "========================================="
echo "✅ Test Complete!"
echo "========================================="
echo
echo "Summary:"
echo " • Release detection: ✅"
echo " • Spec file update: ✅"
echo " • Spec syntax validation: ✅"
echo " • Tarballs available: ✅"
if [[ -n "${JIRA_API_TOKEN:-}" ]]; then
echo " • JIRA creation: ✅ (real ticket created: $JIRA_TICKET)"
else
echo " • JIRA creation: ⏭️ (skipped, no token)"
fi
echo
echo "Next steps to test full workflow:"
echo " 1. Commit this automation to a test branch"
echo " 2. Configure GitLab CI/CD variables (see AUTOMATION-SETUP.md)"
echo " 3. Push the branch to GitLab"
echo " 4. Run pipeline manually: CI/CD → Pipelines → Run Pipeline"
echo " 5. Add variable: TEST_MODE=true for dry-run"
echo
echo "The real workflow will:"
echo " • Download tarballs"
echo " • Upload to lookaside cache with centpkg"
echo " • Create git branch and commit"
echo " • Push to GitLab and create MR"
echo

86
scripts/update-spec.py Executable file
View File

@ -0,0 +1,86 @@
#!/usr/bin/env python3
"""
Update bootc.spec file with new version and changelog entry
"""
import re
import sys
from datetime import datetime
from pathlib import Path
def update_spec(spec_path: str, version: str, jira_ticket: str, author: str = None) -> None:
"""
Update spec file with new version and changelog entry.
Args:
spec_path: Path to the spec file
version: New version number (e.g., "1.5.2")
jira_ticket: JIRA ticket number (e.g., "RHEL-104567")
author: Changelog author (default: bootc-release-bot)
"""
if author is None:
author = "bootc-release-bot <bootc-release-bot@redhat.com>"
spec_file = Path(spec_path)
if not spec_file.exists():
print(f"Error: Spec file not found: {spec_path}", file=sys.stderr)
sys.exit(1)
content = spec_file.read_text()
# Update Version field (preserve spacing)
content = re.sub(
r'^(Version:\s+).*',
rf'\g<1>{version}',
content,
flags=re.MULTILINE
)
# Update Release field to 1%{?dist}
content = re.sub(
r'^(Release:\s+).*',
r'\g<1>1%{?dist}',
content,
flags=re.MULTILINE
)
# Generate changelog entry
date_str = datetime.now().strftime('%a %b %d %Y')
changelog_entry = f"""* {date_str} {author} - {version}-1
- Update to {version}
- Resolves: #{jira_ticket}
"""
# Insert after %changelog line
content = re.sub(
r'(%changelog\n)',
rf'\1{changelog_entry}',
content
)
# Write back
spec_file.write_text(content)
print(f"Updated {spec_path}:")
print(f" Version: {version}")
print(f" Release: 1%{{?dist}}")
print(f" JIRA: {jira_ticket}")
def main():
if len(sys.argv) < 4:
print(f"Usage: {sys.argv[0]} <spec_file> <version> <jira_ticket> [author]", file=sys.stderr)
print(f"Example: {sys.argv[0]} bootc.spec 1.5.2 RHEL-104567", file=sys.stderr)
sys.exit(1)
spec_path = sys.argv[1]
version = sys.argv[2]
jira_ticket = sys.argv[3]
author = sys.argv[4] if len(sys.argv) > 4 else None
update_spec(spec_path, version, jira_ticket, author)
if __name__ == '__main__':
main()

2
sources Normal file
View File

@ -0,0 +1,2 @@
SHA512 (bootc-1.16.2.tar.zstd) = bea618e03cbc0fa6b6876a2e4e69d8181c89b90bec8284748150386ce774ae84471d67edb0d26cbe2d21f4f32ebb7d6ca7a0158891c26a60bdaf1d30af0659d2
SHA512 (bootc-1.16.2-vendor.tar.zstd) = 734b18deadf34ba30b246b06257f8f62aff373e9fa299f8e8b8b3d0c6cd1d203357efd5f31093dfe9ced231f68c3472b5b306e4d526cbe8f0ad9f9ba7e6d4702