bootc/scripts/create-release-mr.sh
gursewak1997 f8bd4576cf 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
2026-07-06 16:42:32 -07:00

235 lines
6.5 KiB
Bash
Executable File

#!/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!"