Skip to content

Development: Use existing builds for protected branches and improve PR lookup to avoid forked PR interference #10719

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

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Changes from 3 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
59 changes: 46 additions & 13 deletions .github/workflows/testserver-deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,33 +47,36 @@ jobs:
needs: log-inputs
outputs:
pr_number: ${{ steps.get_pr.outputs.pr_number }}
pr_head_sha: ${{ steps.get_pr.outputs.pr_head_sha }}
head_sha: ${{ steps.get_pr.outputs.head_sha }}
tag: ${{ steps.get_pr.outputs.tag }}
is_main_branch: ${{ steps.get_pr.outputs.is_main_branch }}
steps:
- name: Check if a PR exists for the branch
id: get_pr
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
BRANCH_NAME=${{ github.event.inputs.branch_name }}
echo "Checking if PR exists for branch: $BRANCH_NAME targeting 'develop'."
IS_MAIN_BRANCH=false

REPO_NAME=${{ github.repository }}
echo "Checking if PR exists for branch: $BRANCH_NAME targeting 'develop' in $REPO_NAME (excluding forks)."

PR_DETAILS=$(gh api repos/${{ github.repository }}/pulls \
--paginate \
--jq ".[] | select(.head.ref == \"$BRANCH_NAME\" and .base.ref == \"develop\") | {number: .number, sha: .head.sha}")
--jq ".[] | select(.head.repo.full_name == \"$REPO_NAME\" and .head.ref == \"$BRANCH_NAME\" and .base.ref == \"develop\") | {number: .number, sha: .head.sha}")

PR_NUMBER=$(echo "$PR_DETAILS" | jq -r ".number")
PR_HEAD_SHA=$(echo "$PR_DETAILS" | jq -r ".sha")

if [ -n "$PR_NUMBER" ] && [ "$PR_NUMBER" != "null" ]; then
echo "Found PR: $PR_NUMBER from branch: $BRANCH_NAME targeting 'develop' with Head: $PR_HEAD_SHA."
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
echo "pr_head_sha=$PR_HEAD_SHA" >> $GITHUB_OUTPUT
echo "head_sha=$PR_HEAD_SHA" >> $GITHUB_OUTPUT
echo "tag=pr-$PR_NUMBER" >> $GITHUB_OUTPUT
else
echo "No PR found for branch: $BRANCH_NAME targeting 'develop'."
echo "pr_number=" >> $GITHUB_OUTPUT
echo "pr_head_sha=" >> $GITHUB_OUTPUT

# Fetch the latest commit SHA of the branch
LATEST_SHA=$(gh api repos/${{ github.repository }}/git/refs/heads/$BRANCH_NAME --jq '.object.sha')
Expand All @@ -84,14 +87,22 @@ jobs:
fi

echo "Latest SHA for branch $BRANCH_NAME is $LATEST_SHA."
# Set tag as branch-SHA
echo "tag=branch-$LATEST_SHA" >> $GITHUB_OUTPUT
echo "head_sha=$LATEST_SHA" >> $GITHUB_OUTPUT

if [[ "$BRANCH_NAME" == "develop" || "$BRANCH_NAME" == "main" ]]; then
IS_MAIN_BRANCH=true
echo "tag=$BRANCH_NAME" >> $GITHUB_OUTPUT
else
# Set tag as branch-SHA
echo "tag=branch-$LATEST_SHA" >> $GITHUB_OUTPUT
fi
fi
echo "is_main_branch=$IS_MAIN_BRANCH" >> $GITHUB_OUTPUT


# Build the Docker image (branch without PR)
conditional-build:
if: ${{ needs.determine-build-context.outputs.pr_number == '' }}
if: ${{ needs.determine-build-context.outputs.pr_number == '' && needs.determine-build-context.outputs.is_main_branch == 'false' }}
needs: determine-build-context
uses: ls1intum/.github/.github/workflows/[email protected]
with:
Expand All @@ -101,7 +112,7 @@ jobs:
tags: ${{ needs.determine-build-context.outputs.tag }}

# Check if the build has run successfully (PR)
check-existing-build:
check-existing-build-for-pull-request:
name: Check Existing Build
if: ${{ needs.determine-build-context.outputs.pr_number != '' }}
needs: determine-build-context
Expand All @@ -111,21 +122,43 @@ jobs:
id: check_build
uses: octokit/[email protected]
with:
route: GET /repos/${{ github.repository }}/actions/workflows/build.yml/runs?event=pull_request&status=success&head_sha=${{ needs.determine-build-context.outputs.pr_head_sha }}
route: GET /repos/${{ github.repository }}/actions/workflows/build.yml/runs?event=pull_request&status=success&head_sha=${{ needs.determine-build-context.outputs.head_sha }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Fail if no successful build found
if: ${{ steps.check_build.conclusion == 'success' && fromJSON(steps.check_build.outputs.data).total_count == 0 }}
run: |
echo "::error::No successful build found for branch '${{ github.event.inputs.branch_name }}' with SHA '${{ needs.determine-build-context.outputs.pr_head_sha }}'."
echo "::error::No successful build found for branch '${{ github.event.inputs.branch_name }}' with SHA '${{ needs.determine-build-context.outputs.head_sha }}'."
exit 1

# Check if the build has run successfully (main branch)
check-existing-build-for-branch:
name: Check Existing Build for Main Branch
if: ${{ needs.determine-build-context.outputs.is_main_branch == 'true' }}
needs: determine-build-context
runs-on: ubuntu-latest
steps:
- name: Get latest successful build for main branch
id: check_main_build
uses: octokit/[email protected]
with:
route: GET /repos/${{ github.repository }}/actions/workflows/build.yml/runs?event=push&status=success&branch=${{ github.event.inputs.branch_name }}&head_sha=${{ needs.determine-build-context.outputs.head_sha }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Fail if no successful build found
if: ${{ steps.check_main_build.conclusion == 'success' && fromJSON(steps.check_main_build.outputs.data).total_count == 0 }}
run: |
echo "::error::No successful build found for branch '${{ github.event.inputs.branch_name }}'."
exit 1


# Deploy to the test-server
deploy:
needs: [ determine-build-context, conditional-build, check-existing-build ]
needs: [ determine-build-context, conditional-build, check-existing-build-for-pull-request, check-existing-build-for-branch ]
# Run if either the conditional-build or check-existing-build job was successful
# Use always() since one of the jobs will always skip
if: always() && (needs.conditional-build.result == 'success' || needs.check-existing-build.result == 'success')
if: always() && (needs.conditional-build.result == 'success' || needs.check-existing-build-for-pull-request.result == 'success' || needs.check-existing-build-for-branch.result == 'success')
name: Deploy to Test-Server
runs-on: ubuntu-latest
environment:
Expand Down