Add automated release pipeline for CentOS Stream
Implements weekly upstream rebase cadence automation: - GitLab CI scheduled pipeline (every 6 hours) - Automatic GitHub release detection - JIRA ticket creation via API - Spec file updates with changelog - Automated MR creation with OSCI Bot integration - TEST_MODE support for safe testing Scripts: - check-upstream-release.sh: Poll GitHub API for new releases - create-release-mr.sh: Main automation orchestrator - update-spec.py: Safe spec file updater - create-jira.sh: JIRA API client - test-workflow.sh: Local testing utility Documentation: - scripts/README.md: Technical documentation - AUTOMATION-SETUP.md: Step-by-step setup guide
This commit is contained in:
parent
336d60ff76
commit
f8bd4576cf
53
.gitlab-ci.yml
Normal file
53
.gitlab-ci.yml
Normal file
@ -0,0 +1,53 @@
|
||||
---
|
||||
# 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
|
||||
216
AUTOMATION-SETUP.md
Normal file
216
AUTOMATION-SETUP.md
Normal 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.
|
||||
242
scripts/README.md
Normal file
242
scripts/README.md
Normal 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
|
||||
65
scripts/check-upstream-release.sh
Executable file
65
scripts/check-upstream-release.sh
Executable 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
102
scripts/create-jira.sh
Executable 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
234
scripts/create-release-mr.sh
Executable 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
142
scripts/test-workflow.sh
Executable 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
86
scripts/update-spec.py
Executable 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()
|
||||
Loading…
Reference in New Issue
Block a user