Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

addition of auto-branching process as part of github action #14385

Merged
merged 1 commit into from
Apr 5, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
317 changes: 317 additions & 0 deletions .github/workflows/auto_branching.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,317 @@
### 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
omkarkhatavkar marked this conversation as resolved.
Show resolved Hide resolved

- 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 }}"
jyejare marked this conversation as resolved.
Show resolved Hide resolved

- 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: |
omkarkhatavkar marked this conversation as resolved.
Show resolved Hide resolved
# 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"
omkarkhatavkar marked this conversation as resolved.
Show resolved Hide resolved
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
"
omkarkhatavkar marked this conversation as resolved.
Show resolved Hide resolved
pr_number=$(gh pr create --title "$title" --body "$body" --base "${{ github.event.inputs.target_branch }}" | awk -F'/' '{print $NF}')
omkarkhatavkar marked this conversation as resolved.
Show resolved Hide resolved
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

omkarkhatavkar marked this conversation as resolved.
Show resolved Hide resolved
- name: git diff
run: git diff

- name: Commit changes
run: |
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
omkarkhatavkar marked this conversation as resolved.
Show resolved Hide resolved
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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not add everything changed?

Suggested change
git add setup.py ./tests/foreman ./robottelo/* ./requirements.txt ./.github/* ./conf/robottelo.yaml.template
git add .

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's often safer to use the explicit approach to avoid accidentally including unintended changes.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In any case, it'll open up a PR for us to review and merge, and if we encounter any accidentally or unintended changes in it, we can manually mitigate them, right?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so it is right approach git add .. I personally never do that on my local machine even. @jyejare @JacobCallahan do you feel the same ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

git add -u only adds file those which are already part of vc and not those are new. So in any case if we add a new file now or later then it would be missed.

So its better to be explicit here.

git commit -m "Changes for new ${{ github.event.inputs.target_branch }} branch"
git remote -vvv
omkarkhatavkar marked this conversation as resolved.
Show resolved Hide resolved
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"]
})