PR Environment Deploy #38
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
name: PR Environment Deploy | |
on: | |
workflow_run: | |
workflows: | |
- PR | |
types: | |
- completed | |
jobs: | |
prepare: | |
runs-on: ubuntu-latest | |
outputs: | |
pr_number: ${{ steps.pr_context.outputs.pr_number }} | |
merge_commit_sha: ${{ steps.pr_context.outputs.merge_commit_sha }} | |
head_repo_owner: ${{ steps.pr_context.outputs.head_repo_owner }} | |
head_repo_name: ${{ steps.pr_context.outputs.head_repo_name }} | |
head_branch: ${{ steps.pr_context.outputs.head_branch }} | |
image_name: ${{ steps.pr_context.outputs.image_name }} | |
image_tag: ${{ steps.pr_context.outputs.image_tag }} | |
image_available: ${{ steps.pr_context.outputs.image_available }} | |
image_digest: ${{ steps.pr_context.outputs.image_digest }} | |
workflow_run_id: ${{ steps.pr_context.outputs.workflow_run_id }} | |
artifact_name: ${{ steps.pr_context.outputs.artifact_name }} | |
artifact_available: ${{ steps.pr_context.outputs.artifact_available }} | |
permissions: | |
contents: read | |
packages: write | |
steps: | |
- name: Dump GitHub context # TODO: remove after debug | |
run: echo "$GITHUB_CONTEXT" | |
env: | |
GITHUB_CONTEXT: ${{ toJson(github) }} | |
- name: Log in to the Container registry | |
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Get PR context | |
id: pr_context | |
run: | | |
#!/bin/bash | |
set -x | |
# Search for PR using the commit SHA and extract all required information | |
PR_DATA=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ | |
"${GITHUB_API_URL}/search/issues?q=${INPUT_HEAD_SHA}+repo:${INPUT_BASE_REPOSITORY}+is:pr+is:open") | |
PR_NUMBER=$(echo "$PR_DATA" | jq -r '.items[0].number') | |
PR_DETAILS=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ | |
"${GITHUB_API_URL}/repos/${INPUT_BASE_REPOSITORY}/pulls/${PR_NUMBER}") | |
MERGE_COMMIT_SHA=$(echo "$PR_DETAILS" | jq -r '.merge_commit_sha') | |
HEAD_REPO_OWNER=$(echo "$PR_DETAILS" | jq -r '.head.repo.owner.login') | |
HEAD_REPO_NAME=$(echo "$PR_DETAILS" | jq -r '.head.repo.name') | |
HEAD_BRANCH=$(echo "$PR_DETAILS" | jq -r '.head.ref') | |
# Search for the image tag in GHCR | |
IMAGE_NAME="${INPUT_BASE_REPOSITORY}" | |
IMAGE_TAG="${MERGE_COMMIT_SHA}" | |
if IMAGE_DIGEST=$(skopeo inspect \ | |
--no-tags \ | |
--retry-times 3 \ | |
--format '{{ .Digest }}' \ | |
"docker://ghcr.io/${IMAGE_NAME}:${IMAGE_TAG}" 2>/dev/null); then | |
IMAGE_AVAILABLE=true | |
else | |
IMAGE_AVAILABLE=false | |
fi | |
# Search for the artifact | |
ARTIFACT_NAME="$MERGE_COMMIT_SHA" | |
ARTIFACTS=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ | |
"${GITHUB_API_URL}/repos/${INPUT_BASE_REPOSITORY}/actions/runs/${INPUT_WORKFLOW_RUN_ID}/artifacts") | |
ARTIFACT_AVAILABLE=$(echo "$ARTIFACTS" | jq --arg name "$ARTIFACT_NAME" '.artifacts | any(.name == $name and .expired == false)') | |
# Exit with error if neither image nor artifact is found | |
if [ "$IMAGE_AVAILABLE" != "true" ] && [ "$ARTIFACT_AVAILABLE" != "true" ]; then | |
echo "Error: Neither image nor image artifact found." | |
exit 1 | |
fi | |
# Create markdown build summary TODO: remove after debug? | |
{ | |
echo "| Variable | Value |" | |
echo "|---------------------|-----------------------|" | |
echo "| pr_number | ${PR_NUMBER} |" | |
echo "| merge_commit_sha | ${MERGE_COMMIT_SHA} |" | |
echo "| head_repo_owner | ${HEAD_REPO_OWNER} |" | |
echo "| head_repo_name | ${HEAD_REPO_NAME} |" | |
echo "| head_branch | ${HEAD_BRANCH} |" | |
echo "| image_name | ${IMAGE_NAME} |" | |
echo "| image_tag | ${IMAGE_TAG} |" | |
echo "| image_available | ${IMAGE_AVAILABLE} |" | |
echo "| image_digest | ${IMAGE_DIGEST} |" | |
echo "| workflow_run_id | ${WORKFLOW_RUN_ID} |" | |
echo "| artifact_name | ${ARTIFACT_NAME} |" | |
echo "| artifact_available | ${ARTIFACT_AVAILABLE} |" | |
} >> "$GITHUB_STEP_SUMMARY" | |
# Set outputs | |
echo "pr_number=$PR_NUMBER" >>$GITHUB_OUTPUT | |
echo "merge_commit_sha=$MERGE_COMMIT_SHA" >>$GITHUB_OUTPUT | |
echo "head_repo_owner=$HEAD_REPO_OWNER" >>$GITHUB_OUTPUT | |
echo "head_repo_name=$HEAD_REPO_NAME" >>$GITHUB_OUTPUT | |
echo "head_branch=$HEAD_BRANCH" >>$GITHUB_OUTPUT | |
echo "image_name=$IMAGE_NAME" >>$GITHUB_OUTPUT | |
echo "image_tag=$IMAGE_TAG" >>$GITHUB_OUTPUT | |
echo "image_available=$IMAGE_AVAILABLE" >>$GITHUB_OUTPUT | |
echo "image_digest=$IMAGE_DIGEST" >>$GITHUB_OUTPUT | |
echo "workflow_run_id=${{ github.event.workflow_run.id }}" >>$GITHUB_OUTPUT | |
echo artifact_name=$ARTIFACT_NAME >>$GITHUB_OUTPUT | |
echo "artifact_available=$ARTIFACT_AVAILABLE" >>$GITHUB_OUTPUT | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
INPUT_BASE_REPOSITORY: ${{ github.repository }} | |
INPUT_HEAD_SHA: ${{ github.event.workflow_run.head_sha }} | |
INPUT_WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id }} | |
plan: | |
needs: | |
- prepare | |
uses: nepalevov/ai-dial-ci/.github/workflows/gh_environment.yml@main | |
with: | |
operation: plan | |
environment_name: "pr-${{ needs.prepare.outputs.pr_number }}" | |
deploy: | |
runs-on: ubuntu-latest | |
permissions: | |
actions: read # Needed to access artifacts | |
packages: write # To push to GHCR | |
contents: read | |
needs: | |
- prepare | |
- plan | |
environment: | |
name: ${{ needs.plan.outputs.environment_name }} | |
steps: | |
- name: Download Artifact from Previous Workflow Run | |
if: ${{ !needs.prepare.outputs.image_available && needs.prepare.outputs.artifact_available }} | |
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 | |
with: | |
name: ${{ needs.prepare.outputs.artifact_name }} | |
path: /tmp | |
run-id: ${{ needs.prepare.outputs.workflow_run_id }} | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Find and Load Docker Image | |
if: ${{ !needs.prepare.outputs.image_available && needs.prepare.outputs.artifact_available }} | |
id: load_image | |
run: | | |
#!/bin/bash | |
ARTIFACT_FILE=/tmp/${INPUT_ARTIFACT_NAME}.tar | |
if [ -f "$ARTIFACT_FILE" ]; then | |
docker load --input "$ARTIFACT_FILE" | |
docker image inspect ghcr.io/${INPUT_IMAGE_NAME}:${INPUT_IMAGE_TAG} | |
echo "image_tag=$IMAGE_TAG" >>$GITHUB_OUTPUT | |
else | |
echo "Artifact file not found" | |
exit 1 | |
fi | |
env: | |
INPUT_ARTIFACT_NAME: ${{ needs.prepare.outputs.artifact_name }} | |
INPUT_IMAGE_NAME: ${{ needs.prepare.outputs.image_name }} | |
INPUT_IMAGE_TAG: ${{ needs.prepare.outputs.image_tag }} | |
# - uses: nepalevov/ai-dial-ci/actions/build_docker@main | |
# with: | |
# ghcr_username: ${{ github.actor }} | |
# ghcr_password: ${{ secrets.ACTIONS_BOT_TOKEN }} | |
# image_name: ghcr.io/${{ github.repository }} | |
# image_tag: ${{ steps.vars.outputs.sha }} | |
# push: true | |
# push_ghcr: true |