auto-branching #1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### The auto-branching workflow triggered through a dispatch request from the CI | |
name: auto-branching | |
# Run on workflow dispatch from CI | |
on: | |
workflow_dispatch: | |
inputs: | |
target_branch: | |
type: string | |
description: branch to be created from the master | |
stream_version: | |
type: string | |
description: new stream version of satellite | |
jobs: | |
check-group-membership: | |
runs-on: ubuntu-latest | |
outputs: | |
member: ${{steps.check_membership.outputs.member}} | |
steps: | |
- name: Check if the user is a member of repository-admins group | |
id: check_membership | |
run: | | |
# Use GitHub API to check if the user triggering the workflow is a member of satellite-admin group | |
MEMBER=$(curl -s -H "Authorization: token ${{ secrets._REPO_ADMIN_TOKEN }}" \ | |
"https://api.github.com/orgs/satelliteQE/teams/repository-admins/memberships/${{ github.actor }}") | |
if [[ $(echo "$MEMBER" | jq -r '.state') == "active" ]]; then | |
echo "User is a member of satellite-admin group." | |
echo "member=true" >> $GITHUB_OUTPUT | |
else | |
echo "User is not a member of satellite-admin group." | |
echo "member=false" >> $GITHUB_OUTPUT | |
exit 1 | |
fi | |
auto-branching-new-downstream-release: | |
name: ${{ github.event.inputs.target_branch }} - raise PR with changes | |
runs-on: ubuntu-latest | |
needs: check-group-membership | |
if: ${{ needs.check-group-membership.outputs.member == 'true' }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Create the ${{ github.event.inputs.target_branch }} branch | |
id: create-branch | |
uses: peterjgrainger/[email protected] | |
env: | |
GITHUB_TOKEN: ${{ secrets._REPO_ADMIN_TOKEN }} | |
with: | |
branch: ${{ github.event.inputs.target_branch }} | |
- name: Create label for the ${{ github.event.inputs.target_branch }} branch | |
id: create-label | |
run: | | |
curl -X POST \ | |
-H "Authorization: token ${{ secrets._REPO_ADMIN_TOKEN }}" \ | |
-H "Accept: application/vnd.github.v3+json" \ | |
https://api.github.com/repos/${{ github.repository }}/labels \ | |
-d "{\"name\":\"${{ github.event.inputs.target_branch }}\",\"color\":\"fbca04\"}" | |
- name: Switch to ${{ github.event.inputs.target_branch }} branch | |
run: git checkout -b "${{ github.event.inputs.target_branch }}" | |
- name: Checkout from ${{ github.event.inputs.target_branch }} branch for auto-branching changes | |
id: checkout-to-auto-branch | |
run: | | |
branch_name="auto-branching-${{ github.event.inputs.target_branch }}-$(date '+%s')" | |
git checkout -b "$branch_name" | |
echo "branch_name=$branch_name" >> $GITHUB_OUTPUT | |
- name: Update target branch label in dependabot yml file | |
id: update-dependabot | |
run: | | |
# Read the dependabot.yml file | |
FILE_PATH="./.github/dependabot.yml" | |
TARGET_BRANCH="${{ github.event.inputs.target_branch }}" | |
# Append the target branch label to the labels node | |
awk -v target="'$TARGET_BRANCH'" '/^ *labels:/ {$0 = $0 "\n - " target} 1' "$FILE_PATH" > temp.yml && mv temp.yml "$FILE_PATH" | |
- name: Update repository URLs in requirements.txt | |
id: update-repo-urls | |
run: | | |
# Define the file path | |
FILE_PATH="./requirements.txt" | |
# Define the replacement strings | |
replacements=( | |
"airgun @ git+https://github.com/SatelliteQE/airgun.git@master#egg=airgun|airgun @ git+https://github.com/SatelliteQE/airgun.git@${{ github.event.inputs.target_branch }}#egg=airgun" | |
"nailgun @ git+https://github.com/SatelliteQE/nailgun.git@master#egg=nailgun|nailgun @ git+https://github.com/SatelliteQE/nailgun.git@${{ github.event.inputs.target_branch }}#egg=nailgun" | |
) | |
# Create a temporary file | |
TEMP_FILE=$(mktemp) | |
# Perform replacements using a for loop | |
for replacement in "${replacements[@]}"; do | |
old_url=$(echo "$replacement" | cut -d'|' -f1) | |
new_url=$(echo "$replacement" | cut -d'|' -f2) | |
sed "s|${old_url}|${new_url}|g" "$FILE_PATH" > "$TEMP_FILE" && mv "$TEMP_FILE" "$FILE_PATH" | |
done | |
- name: Remove the dispatch release GHA | |
id: remove-dispatch-release-gha | |
run: | | |
rm -rf ./.github/workflows/dispatch_release.yml | |
rm -rf ./.github/workflows/auto_branching.yml | |
- name: Remove lines with @pytest.mark.stream | |
id: remove-mark-stream | |
run: | | |
# Loop through files in the folder | |
grep -rl "tests/foreman" -e '@pytest\.mark\.stream' | while IFS= read -r file; do | |
awk '!/@pytest\.mark\.stream/' "$file" > temp && mv temp "$file" | |
done | |
- name: Update version in setup.py | |
run: sed -i "s/version=['\"][0-9.]*['\"]\+/version='${{ github.event.inputs.target_branch }}'/" setup.py | |
- name: Update the Constants in __init__.py file | |
run: | | |
old_url="https://raw.githubusercontent.com/SatelliteQE/robottelo/master/tests/foreman/data/uri.sh" | |
new_url="https://raw.githubusercontent.com/SatelliteQE/robottelo/${{ github.event.inputs.target_branch }}/tests/foreman/data/uri.sh" | |
FILE_PATH="./robottelo/constants/__init__.py" | |
awk '/SAT_NON_GA_VERSIONS =/ { sub(/\[[^,]*, /, "[", $0) } 1' "$FILE_PATH" > temp && mv temp "$FILE_PATH" | |
sed -i.bak "s|${old_url}|${new_url}|" "$FILE_PATH" | |
rm "$FILE_PATH.bak" | |
- name: git status | |
run: git status | |
- name: git diff | |
run: git diff | |
- name: Commit changes | |
run: | | |
git config --local user.email Satellite-QE.satqe.com && git config --local user.name Satellite-QE | |
git add setup.py ./tests/foreman ./robottelo/* ./requirements.txt ./.github/* | |
git commit -m "Changes for ${{ github.event.inputs.target_branch }} new branch" | |
git push origin ${{steps.checkout-to-auto-branch.outputs.branch_name}} | |
- name: Create pull request | |
id: create_pr | |
run: | | |
title="[${{ github.event.inputs.target_branch }}]: Changes for ${{ github.event.inputs.target_branch }} new branch" | |
body=" | |
### Problem Statement | |
New ${{ github.event.inputs.target_branch }} branch | |
### Solution | |
- Dependabot labels are updated for new branch | |
- Removed dispatch release GHA from ${{ github.event.inputs.target_branch }} as we are releasing only master changes | |
- Airgun and Nailgun Requirements uses ${{ github.event.inputs.target_branch }} branch | |
- Constants are using new version now | |
- Stream tests removed | |
- Setup.py uses new version | |
" | |
pr_number=$(gh pr create --title "$title" --body "$body" --base "${{ github.event.inputs.target_branch }}" | awk -F'/' '{print $NF}') | |
echo "$pr_number" | |
echo "pr_number=$pr_number" >> $GITHUB_OUTPUT | |
env: | |
GITHUB_TOKEN: ${{ secrets._REPO_ADMIN_TOKEN }} | |
- name: Add the prt comment for running the sanity tests | |
id: add-parent-prt-comment | |
uses: thollander/actions-comment-pull-request@v2 | |
with: | |
message: | | |
trigger: test-robottelo | |
pr_number: ${{ steps.create_pr.outputs.pr_number }} | |
GITHUB_TOKEN: ${{ secrets._REPO_ADMIN_TOKEN }} | |
- name: add the no-cherrypick label | |
uses: actions/github-script@v7 | |
with: | |
github-token: ${{ secrets._REPO_ADMIN_TOKEN }} | |
script: | | |
github.rest.issues.addLabels({ | |
issue_number: ${{ steps.create_pr.outputs.pr_number }}, | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
labels: ["No-CherryPick"] | |
}) | |
branch-protection: | |
runs-on: ubuntu-latest | |
needs: auto-branching-new-downstream-release | |
if: success() | |
steps: | |
- name: Create branch protection | |
run: | | |
TOKEN=${{ secrets._REPO_ADMIN_TOKEN }} | |
OWNER=${{ github.repository_owner }} | |
REPO=${{ github.event.repository.name }} | |
BRANCH="${{ github.event.inputs.target_branch }}" # Adjust branch name as needed | |
# Branch protection payload | |
PROTECTION_PAYLOAD='{ | |
"required_status_checks": { | |
"strict": true, | |
"contexts": ["Code Quality (3.10)", "Code Quality (3.11)", "Code Quality (3.12)", "Enforcing cherrypick labels"] | |
}, | |
"required_linear_history": true, | |
"enforce_admins": null, | |
"required_pull_request_reviews": null, | |
"restrictions": null, | |
"allow_force_pushes": null, | |
"allow_deletions": null | |
}' | |
# Call GitHub API to update branch protection | |
PROTECTION_RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \ | |
-X PUT \ | |
-H "Accept: application/vnd.github.luke-cage-preview+json" \ | |
-H "Authorization: token $TOKEN" \ | |
-d "$PROTECTION_PAYLOAD" \ | |
"https://api.github.com/repos/$OWNER/$REPO/branches/$BRANCH/protection") | |
if [[ $PROTECTION_RESPONSE -eq 200 ]]; then | |
echo "Branch protection successfully updated." | |
echo "protection-outcome=success" >> "$GITHUB_OUTPUT" | |
else | |
echo "Failed to update branch protection. HTTP status code: $PROTECTION_RESPONSE" | |
echo "protection-outcome=failure" >> "$GITHUB_OUTPUT" | |
exit 1 | |
fi | |
auto-branching-master: | |
name: master - raise PR with changes | |
runs-on: ubuntu-latest | |
needs: check-group-membership | |
if: ${{ needs.check-group-membership.outputs.member == 'true' }} | |
steps: | |
- name: Checkout Robottelo | |
uses: actions/checkout@v4 | |
- name: Update target branch label in dependabot yml file | |
id: update-dependabot | |
run: | | |
# Read the dependabot.yml file | |
FILE_PATH="./.github/dependabot.yml" | |
TARGET_BRANCH="${{ github.event.inputs.target_branch }}" | |
# Append the target branch label to the labels node | |
awk -v target="'$TARGET_BRANCH'" '/^ *labels:/ {$0 = $0 "\n - " target} 1' "$FILE_PATH" > temp.yml && mv temp.yml "$FILE_PATH" | |
- name: Remove lines with @pytest.mark.stream | |
id: remove-mark-stream | |
run: | | |
# Loop through files in the folder | |
grep -rl "tests/foreman" -e '@pytest\.mark\.stream' | while IFS= read -r file; do | |
awk '!/@pytest\.mark\.stream/' "$file" > temp && mv temp "$file" | |
done | |
- name: Update the Constants in __init__.py file | |
run: | | |
version="${{ github.event.inputs.target_branch }}" | |
ga_version="${{ github.event.inputs.ga_version }}" | |
old_stream_version="${version%.z}" | |
new_stream_version="${{ github.event.inputs.stream_version }}" | |
non_ga_versions="['$old_stream_version', '$new_stream_version']" | |
FILE_PATH="./robottelo/constants/__init__.py" | |
# update the version | |
sed -i.bak "s/SATELLITE_VERSION = \"$old_stream_version\"/SATELLITE_VERSION = \"$new_stream_version\"/" "$FILE_PATH" | |
sed -i.bak "s/ SATELLITE_VERSION: \"$old_stream_version\"/ SATELLITE_VERSION: \"$new_stream_version\"/" ./conf/robottelo.yaml.template | |
sed -i.bak "s/SAT_NON_GA_VERSIONS = \[.*\]/SAT_NON_GA_VERSIONS = $non_ga_versions/" "$FILE_PATH" | |
rm "$FILE_PATH.bak" "./conf/robottelo.yaml.template.bak" | |
- name: git status | |
run: git status | |
- name: git diff | |
run: git diff | |
- name: Commit changes | |
run: | | |
git config --local user.email "[email protected]" | |
git config --local user.name "GitHub Action" | |
branch_name="auto-branching-${{ github.event.inputs.target_branch }}-$(date '+%s')" | |
git checkout -b "$branch_name" | |
git add setup.py ./tests/foreman ./robottelo/* ./requirements.txt ./.github/* ./conf/robottelo.yaml.template | |
git commit -m "Changes for new ${{ github.event.inputs.target_branch }} branch" | |
git remote -vvv | |
git push origin "$branch_name" | |
- name: Create pull request | |
id: create_pr | |
run: | | |
title="[master]: Changes for new ${{ github.event.inputs.target_branch }} branch" | |
body=" | |
### Problem Statement | |
New ${{ github.event.inputs.target_branch }} downstream and master points to stream that is ${{ github.event.inputs.stream_version }} | |
### Solution | |
- Dependabot.yaml cherrypicks to ${{ github.event.inputs.target_branch }} | |
- Robottelo conf and constants now uses ${{ github.event.inputs.stream_version }} and ${{ github.event.inputs.target_branch }} satellite versions | |
" | |
pr_number=$(gh pr create --title "$title" --body "$body" --base "master" | awk -F'/' '{print $NF}') | |
echo "$pr_number" | |
echo "pr_number=$pr_number" >> $GITHUB_OUTPUT | |
env: | |
GITHUB_TOKEN: ${{ secrets._REPO_ADMIN_TOKEN }} | |
- name: Add the prt comment for running the sanity tests | |
id: add-parent-prt-comment | |
uses: thollander/actions-comment-pull-request@v2 | |
with: | |
message: | | |
trigger: test-robottelo | |
pr_number: ${{ steps.create_pr.outputs.pr_number }} | |
GITHUB_TOKEN: ${{ secrets._REPO_ADMIN_TOKEN }} | |
- name: add the no-cherrypick label | |
uses: actions/github-script@v7 | |
with: | |
github-token: ${{ secrets._REPO_ADMIN_TOKEN }} | |
script: | | |
github.rest.issues.addLabels({ | |
issue_number: ${{ steps.create_pr.outputs.pr_number }}, | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
labels: ["No-CherryPick"] | |
}) |