From 2f8af6b1cad3c222756a4b3bb8ebc3d6b3382fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B4=D8=B1=D9=83=D8=A9=20=D8=AE=D8=A8=D9=8A=D8=B1=20?= =?UTF-8?q?=D8=A7=D9=84=D9=85=D8=AD=D8=AF=D9=88=D8=AF=D8=A9?= Date: Fri, 21 Nov 2025 23:50:12 +0200 Subject: [PATCH] Restrict PR authors and validate committers Updated GitHub Actions workflow to restrict PR authors and committers. Added validation step for allowed authors. --- .github/workflows/dev-preprod-servers.yml | 212 ++++++++++------------ 1 file changed, 91 insertions(+), 121 deletions(-) diff --git a/.github/workflows/dev-preprod-servers.yml b/.github/workflows/dev-preprod-servers.yml index d21f6f5a5..72c844b85 100644 --- a/.github/workflows/dev-preprod-servers.yml +++ b/.github/workflows/dev-preprod-servers.yml @@ -1,14 +1,18 @@ -name: Dev/Preprod Servers - Pull Code +name: Restrict PR Authors & Committers + +permissions: + contents: read + pull-requests: write on: - push: + pull_request: + types: [opened, reopened, synchronize] branches: - dev_odex-event - dev_odex25_accounting - dev_odex25_base - dev_odex25_dms - dev_odex25_fleet - - dev_odex25_helpdesk - dev_odex25_hr - dev_odex25_inventory - dev_odex25_maintenance @@ -23,7 +27,9 @@ on: - dev_odex25_website - dev_openeducat_erp-14.0.1.0 - dev_odex25_ensan + - dev_odex25_helpdesk - dev_odex25_donation + - preprod_odex-event - preprod_odex25_accounting - preprod_odex25_base @@ -46,126 +52,90 @@ on: - preprod_odex25_ensan - preprod_odex25_donation - workflow_dispatch: - inputs: - environment: - description: 'Select Server' - required: true - type: choice - options: - - dev - - preprod - default: dev + - master_odex-event + - master_odex25_accounting + - master_odex25_base + - master_odex25_dms + - master_odex25_fleet + - master_odex25_helpdesk + - master_odex25_hr + - master_odex25_inventory + - master_odex25_maintenance + - master_odex25_mobile + - master_odex25_pos + - master_odex25_project + - master_odex25_purchase + - master_odex25_realstate + - master_odex25_sales + - master_odex25_survey + - master_odex25_transactions + - master_odex25_website + - master_openeducat_erp-14.0.1.0 + - master_odex25_ensan + - master_odex25_donation jobs: + validate: + runs-on: linting_odex25-standard-modules_runner - deploy_preprod_server: - name: Deploy to Preprod Servers - runs-on: app-sever-project-runner - if: | - (github.ref == 'refs/heads/preprod_odex-event' || - github.ref == 'refs/heads/preprod_odex25_accounting' || - github.ref == 'refs/heads/preprod_odex25_base' || - github.ref == 'refs/heads/preprod_odex25_dms' || - github.ref == 'refs/heads/preprod_odex25_fleet' || - github.ref == 'refs/heads/preprod_odex25_helpdesk' || - github.ref == 'refs/heads/preprod_odex25_hr' || - github.ref == 'refs/heads/preprod_odex25_inventory' || - github.ref == 'refs/heads/preprod_odex25_maintenance' || - github.ref == 'refs/heads/preprod_odex25_mobile' || - github.ref == 'refs/heads/preprod_odex25_pos' || - github.ref == 'refs/heads/preprod_odex25_project' || - github.ref == 'refs/heads/preprod_odex25_purchase' || - github.ref == 'refs/heads/preprod_odex25_realstate' || - github.ref == 'refs/heads/preprod_odex25_sales' || - github.ref == 'refs/heads/preprod_odex25_survey' || - github.ref == 'refs/heads/preprod_odex25_transactions' || - github.ref == 'refs/heads/preprod_odex25_website' || - github.ref == 'refs/heads/preprod_openeducat_erp-14.0.1.0' || - github.ref == 'refs/heads/preprod_odex25_ensan' || - github.ref == 'refs/heads/preprod_odex25_donation') - || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'preprod') steps: - - name: Checkout And Restart Project - run: | - sudo chmod +x /home/${{ secrets.CLIENT_USER }}/scripts/pull/preprod_pull_standard_code.sh - sudo /home/${{ secrets.CLIENT_USER }}/scripts/pull/preprod_pull_standard_code.sh - sudo systemctl restart ${{ secrets.ENSAN_APP_PREPROD_SERVICE }} ${{ secrets.ODEX25_GENERAL_PREPROD_SERVICE }} ${{ secrets.ODEX25_STANDARD_PREPROD_SERVICE }} ${{ secrets.TWAHOD_APP_PREPROD_SERVICE }} ${{ secrets.ODEX25_DEMO_PREPROD_SERVICE }} ${{ secrets.HELPDESK_PREPROD_SERVICE }} ${{ secrets.CYBER_APP_PREPROD_SERVICE }} ${{ secrets.JAZALA_APP_PREPROD_SERVICE }} - if [ $? -eq 0 ]; then - echo "** [INFO] "PREPROD" services have been restarted." - else - echo "** [ERROR] Failed to restart "PREPROD" services." - fi - - deploy_test_server: - name: Deploy to Dev Servers - runs-on: app-sever-project-runner - if: | - (github.ref == 'refs/heads/dev_odex-event' || - github.ref == 'refs/heads/dev_odex25_accounting' || - github.ref == 'refs/heads/dev_odex25_base' || - github.ref == 'refs/heads/dev_odex25_dms' || - github.ref == 'refs/heads/dev_odex25_fleet' || - github.ref == 'refs/heads/dev_odex25_helpdesk' || - github.ref == 'refs/heads/dev_odex25_hr' || - github.ref == 'refs/heads/dev_odex25_inventory' || - github.ref == 'refs/heads/dev_odex25_maintenance' || - github.ref == 'refs/heads/dev_odex25_mobile' || - github.ref == 'refs/heads/dev_odex25_pos' || - github.ref == 'refs/heads/dev_odex25_project' || - github.ref == 'refs/heads/dev_odex25_purchase' || - github.ref == 'refs/heads/dev_odex25_realstate' || - github.ref == 'refs/heads/dev_odex25_sales' || - github.ref == 'refs/heads/dev_odex25_survey' || - github.ref == 'refs/heads/dev_odex25_transactions' || - github.ref == 'refs/heads/dev_odex25_website' || - github.ref == 'refs/heads/dev_openeducat_erp-14.0.1.0' || - github.ref == 'refs/heads/dev_odex25_ensan' || - github.ref == 'refs/heads/dev_odex25_donation') - || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'dev') - steps: - - name: Checkout And Restart Project - run: | - sudo chmod +x /home/${{ secrets.CLIENT_USER }}/scripts/pull/dev_pull_standard_code.sh - sudo /home/${{ secrets.CLIENT_USER }}/scripts/pull/dev_pull_standard_code.sh - sudo systemctl restart ${{ secrets.ENSAN_APP_TEST_SERVICE }} ${{ secrets.ODEX25_GENERAL_TEST_SERVICE }} ${{ secrets.ODEX25_STANDARD_TEST_SERVICE }} ${{ secrets.TWAHOD_APP_TEST_SERVICE }} ${{ secrets.HELPDESK_TEST_SERVICE }} ${{ secrets.KAZ_LIBRARY_TEST_SERVICE }} ${{ secrets.CYBER_APP_TEST_SERVICE }} ${{ secrets.JAZALA_APP_TEST_SERVICE }} - if [ $? -eq 0 ]; then - echo "** [INFO] "DEV" services have been restarted." - else - echo "** [ERROR] Failed to restart "DEV" services." - fi + - name: Validate PR Author & Commit Authors + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.PR_CLOSE_TOKEN }} + script: | + const allowed = [ + "expsa", + "ronozoro", + "Abubaker-Altaib", + "altexp", + "the5abir", + "ahmadaking", + "kchyounes19", + "abdurrahman-saber" + ]; - ensan_vpn_stage_server: - name: Deploy to Ensan Stage - runs-on: new-ensan-vpn-client-server-runner - if: | - (github.ref == 'refs/heads/preprod_odex-event' || - github.ref == 'refs/heads/preprod_odex25_accounting' || - github.ref == 'refs/heads/preprod_odex25_base' || - github.ref == 'refs/heads/preprod_odex25_dms' || - github.ref == 'refs/heads/preprod_odex25_fleet' || - github.ref == 'refs/heads/preprod_odex25_helpdesk' || - github.ref == 'refs/heads/preprod_odex25_hr' || - github.ref == 'refs/heads/preprod_odex25_inventory' || - github.ref == 'refs/heads/preprod_odex25_maintenance' || - github.ref == 'refs/heads/preprod_odex25_mobile' || - github.ref == 'refs/heads/preprod_odex25_pos' || - github.ref == 'refs/heads/preprod_odex25_project' || - github.ref == 'refs/heads/preprod_odex25_purchase' || - github.ref == 'refs/heads/preprod_odex25_realstate' || - github.ref == 'refs/heads/preprod_odex25_sales' || - github.ref == 'refs/heads/preprod_odex25_survey' || - github.ref == 'refs/heads/preprod_odex25_transactions' || - github.ref == 'refs/heads/preprod_odex25_website' || - github.ref == 'refs/heads/preprod_openeducat_erp-14.0.1.0' || - github.ref == 'refs/heads/preprod_odex25_ensan' || - github.ref == 'refs/heads/preprod_odex25_donation') - || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'preprod') - steps: - - name: Checkout And Restart Project - run: | - echo "** [INFO] Running on branch --> ${GITHUB_REF#refs/heads/}" - sudo chmod +x ${{ secrets.ENSAN_STANDARD_FOLDER_PATH }}/scripts/pull_code.sh - sudo ${{ secrets.ENSAN_STANDARD_FOLDER_PATH }}/scripts/pull_code.sh ${{ secrets.ENSAN_PROJECT_USER }} ${{ secrets.ENSAN_STANDARD_FOLDER_PATH }} ${{ secrets.ENSAN_STAGE_SERVICE }} preprod ${GITHUB_REF#refs/heads/preprod_} ${GITHUB_REF#refs/heads/} ${{ secrets.GH_TOKEN }} - - + const pr = context.payload.pull_request; + const prAuthor = pr.user.login; + const owner = context.repo.owner; + const repo = context.repo.repo; + + core.info(`PR author: ${prAuthor}`); + + // Check PR author + if (!allowed.includes(prAuthor)) { + core.error(`Unauthorized PR author: ${prAuthor}. Closing PR...`); + await github.rest.pulls.update({ + owner, + repo, + pull_number: pr.number, + state: "closed" + }); + return; + } + + // Check commit authors + const commitList = await github.rest.pulls.listCommits({ + owner, + repo, + pull_number: pr.number + }); + + for (const commit of commitList.data) { + const commitAuthor = commit.author ? commit.author.login : null; + + if (commitAuthor && !allowed.includes(commitAuthor)) { + core.error(`Unauthorized commit author: ${commitAuthor}. Closing PR...`); + + await github.rest.pulls.update({ + owner, + repo, + pull_number: pr.number, + state: "closed" + }); + + return; + } + } + + core.info("All PR authors and committers are allowed.");