diff --git a/.github/workflows/github-actions-manual-update-rules.yml b/.github/workflows/github-actions-manual-update-rules.yml deleted file mode 100644 index fc10dae30d..0000000000 --- a/.github/workflows/github-actions-manual-update-rules.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: Manually Trigger Update Rules -on: - workflow_dispatch: - inputs: - type: - description: 'Type of update (overwrite or normal)' - required: true - default: 'normal' - -jobs: - update: - runs-on: ubuntu-latest - strategy: - fail-fast: false - steps: - - name: Check out repository code recursively - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - uses: actions/setup-python@v4 - with: - python-version: "3.10" - - name: Install Python Packages - run: | - pip install firebase-admin - - name: Execute Python Script Update - env: - CREDS_FILE: ${{ secrets.CREDS_FILE }} - API_BASE_URL: ${{ secrets.API_BASE_URL }} - run: | - if [[ "${{ github.event.inputs.type }}" == "overwrite" ]]; then - python flow/util/updateRules.py --keyFile "${CREDS_FILE}" --apiURL ${API_BASE_URL} --commitSHA $(git rev-parse HEAD) --overwrite - else - python flow/util/updateRules.py --keyFile "${CREDS_FILE}" --apiURL ${API_BASE_URL} --commitSHA $(git rev-parse HEAD) - fi - - name: Push updated rules - id: remote-update - run: | - git config --local user.email "github-actions[bot]@users.noreply.github.com" - git config --local user.name "github-actions[bot]" - if [ -n "$(git status --porcelain)" ]; then - echo "has_update=true" >> "$GITHUB_OUTPUT" - else - echo "has_update=false" >> "$GITHUB_OUTPUT" - fi - git add . - git commit --signoff -m "flow: update rules based on new golden reference" - - if: "steps.remote-update.outputs.has_update == 'true'" - name: update rules pr - id: remote-update-pr - run: | - git push diff --git a/.github/workflows/github-actions-update-rules.yml b/.github/workflows/github-actions-update-rules.yml index c728f90df9..2748dd3130 100644 --- a/.github/workflows/github-actions-update-rules.yml +++ b/.github/workflows/github-actions-update-rules.yml @@ -1,71 +1,84 @@ -name: Create draft PR for updated rules +name: Update Rules + on: - repository_dispatch: - types: - - set-new-golden + pull_request: + types: [labeled] jobs: - update: + update-rules: + if: contains(github.event.label.name, 'Update Rules') runs-on: ubuntu-latest - strategy: - fail-fast: false steps: - - name: Check out repository code recursively + - name: Check out PR code uses: actions/checkout@v3 with: - fetch-depth: 0 - - name: Git prep - run: | - git config --add remote.origin.fetch "+refs/pull/*/head:refs/remotes/origin/pr/*" - git fetch - git checkout "origin/pr/${{ github.event.client_payload.branch }}" - - uses: actions/setup-python@v4 + ref: ${{ github.event.pull_request.head.ref }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 1 + + - name: Set up Python 3.10 + uses: actions/setup-python@v4 with: python-version: "3.10" + - name: Install Python Packages run: | pip install firebase-admin + + - name: Query Jenkins Build Status + id: query_jenkins + run: | + .github/workflows/jenkins-check-build.sh "${{ github.event.pull_request.number }}" + - name: Execute Python Script Update env: CREDS_FILE: ${{ secrets.CREDS_FILE }} API_BASE_URL: ${{ secrets.API_BASE_URL }} run: | - echo ${{ github.event_name }} - echo ${{ github.event.client_payload.type }} - if [[ "${{ github.event_name }}" == "repository_dispatch" && "${{ github.event.client_payload.type }}" == "overwrite" ]]; then - python flow/util/updateRules.py --keyFile "${CREDS_FILE}" --apiURL ${API_BASE_URL} --commitSHA ${{ github.event.client_payload.commitsha }} --overwrite - else - python flow/util/updateRules.py --keyFile "${CREDS_FILE}" --apiURL ${API_BASE_URL} --commitSHA ${{ github.event.client_payload.commitsha }} + set -e + COMMIT_SHA=$(git rev-parse HEAD) + echo "PR has commit sha: $COMMIT_SHA" + COMMIT_SHA=abbc09da7f92f176a669e72d52653b80f074c12e + echo "${CREDS_FILE}" > creds.json + ls -lh creds.json + cat creds.json + if [[ "${{ github.event.label.name }}" == "Update Rules Overwrite" ]]; then + echo "Calling updateRules.py with overwrite." + python flow/util/updateRules.py --keyFile creds.json \ + --apiURL "${API_BASE_URL}" \ + --commitSHA "${COMMIT_SHA}" \ + --overwrite + else + echo "Calling updateRules.py" + python flow/util/updateRules.py --keyFile creds.json \ + --apiURL "${API_BASE_URL}" \ + --commitSHA "${COMMIT_SHA}" fi - - name: Push updated rules - id: remote-update + + - name: Check for changes and commit + id: check-and-commit run: | git config --local user.email "github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" if [ -n "$(git status --porcelain)" ]; then - echo "has_update=true" >> "$GITHUB_OUTPUT" + git add . + git commit --signoff -m "flow: update rules" + echo "has_update=true" >> "$GITHUB_ENV" else - echo "has_update=false" >> "$GITHUB_OUTPUT" + echo "has_update=false" >> "$GITHUB_ENV" fi - git add . - git commit --signoff -m "flow: update rules based on new golden reference" - - if: "github.event.client_payload.branch != 'master'" - name: update rules pr - id: remote-update-pr + + - name: Push changes + if: env.has_update == 'true' run: | - git push origin "HEAD:refs/pull/${{ github.event.client_payload.branch }}/head" - - if: "steps.remote-update.outputs.has_update == 'true' && github.event.client_payload.branch == 'master'" - name: Create Draft PR - uses: peter-evans/create-pull-request@v5 + git push + + - name: Remove label from PR + if: always() + uses: actions-ecosystem/action-remove-labels@v1 + env: + LABEL: ${{ github.event.label.name }} with: - token: ${{ github.token }} - signoff: true - delete-branch: true - title: "[BOT] Update rules" - reviewers: | - vvbandeira - maliberty - draft: true - branch: bot-update-rules - commit-message: | - [BOT] Update rules + github_token: ${{ secrets.GITHUB_TOKEN }} + labels: "${LABEL}" diff --git a/.github/workflows/jenkins-check-build.sh b/.github/workflows/jenkins-check-build.sh new file mode 100755 index 0000000000..750a6b0900 --- /dev/null +++ b/.github/workflows/jenkins-check-build.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +# Check if exactly one argument is provided +if [ "$#" -ne 1 ]; then + echo "Error: Only argument required is the PR number." + exit 1 +fi + +# Check if the argument is numerical +if ! [[ "$1" =~ ^[0-9]+$ ]]; then + echo "Error: The argument must be a numerical value." + exit 1 +fi +PR_NUMBER="$1" + +JENKINS_URL="https://jenkins.openroad.tools/job/OpenROAD-flow-scripts-Public" +PR_BUILD_URL="${JENKINS_URL}/job/PR-${PR_NUMBER}-merge" + +while true; do + + if ! curl -s "${PR_BUILD_URL}/api/json?pretty" | jq . > /dev/null 2>&1 ; then + echo "Error while checking PR ${PR_NUMBER}" + exit 1 + fi + + echo "Checking if build is in queue..." + in_queue=$(curl -s "${PR_BUILD_URL}/api/json?pretty" | jq -r '.inQueue') + if [ "$in_queue" == "true" ]; then + echo "Build still in queue. Retrying..." + sleep 30 + continue + fi + echo "Build not in queue." + + echo "Getting latest build ID..." + LAST_BUILD_ID=$(curl -s "${PR_BUILD_URL}/api/json?pretty" | jq -r '.lastBuild.number') + LAST_BUILD_ID=1 + if [ "$LAST_BUILD_ID" == "null" ]; then + echo "Build id is null." + exit 1 + fi + if [ -z "$LAST_BUILD_ID" ]; then + echo "No build found. Retrying..." + sleep 30 + continue + fi + echo "Latest build id ${LAST_BUILD_ID}" + + echo "Checking if build is done..." + BUILD_URL="${PR_BUILD_URL}/${LAST_BUILD_ID}/api/json?pretty" + in_progress=$(curl -s "$BUILD_URL" | jq -r '.inProgress') + if [ "$in_progress" == "false" ]; then + echo "Build complete. Running Python script..." + break + else + echo "Build still in progress. Waiting for completion..." + sleep 30 + fi + +done diff --git a/flow/util/updateRules.py b/flow/util/updateRules.py index c565b2afbe..b0d8730dbe 100644 --- a/flow/util/updateRules.py +++ b/flow/util/updateRules.py @@ -11,9 +11,6 @@ from genRuleFile import update_rules from genRuleFile import get_metrics -# make sure the working dir is flow/ -os.chdir(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')) - # Create the argument parser parser = argparse.ArgumentParser(description='Process some integers.') @@ -26,7 +23,8 @@ args = parser.parse_args() # Initialize Firebase Admin SDK with service account credentials -cred = credentials.Certificate(json.loads(args.keyFile)) +with open(args.keyFile) as file: + cred = credentials.Certificate(json.load(file)) firebase_admin.initialize_app(cred) # Initialize Firestore client @@ -34,8 +32,13 @@ api_base_url = args.apiURL +# make sure the working dir is flow/ +os.chdir(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')) + runFilename = f'rules-base.json' +exit(0) + for designsDir, dirs, files in sorted(os.walk('designs', topdown=False)): dirList = designsDir.split(os.sep) if len(dirList) != 3: @@ -58,4 +61,4 @@ "base", # variant metrics, # metrics needed for update, default is {} in case of file args.overwrite # overwrite flag, default is false - ) \ No newline at end of file + )