PR Environment Deploy #44
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 | |
permissions: | |
contents: read | |
packages: write | |
outputs: | |
pr_number: ${{ steps.context.outputs.pr_number }} | |
merge_commit_sha: ${{ steps.context.outputs.merge_commit_sha }} | |
head_repo_owner: ${{ steps.context.outputs.head_repo_owner }} | |
head_repo_name: ${{ steps.context.outputs.head_repo_name }} | |
head_branch: ${{ steps.context.outputs.head_branch }} | |
image_available: ${{ steps.copy.outputs.image_available || steps.context.outputs.image_available }} | |
image_name: ${{ steps.copy.outputs.image_name || steps.context.outputs.image_name }} | |
image_tag: ${{ steps.copy.outputs.image_tag || steps.context.outputs.image_tag }} | |
image_digest: ${{ steps.context.outputs.image_digest }} | |
workflow_run_id: ${{ steps.context.outputs.workflow_run_id }} | |
artifact_name: ${{ steps.context.outputs.artifact_name }} | |
artifact_available: ${{ steps.context.outputs.artifact_available }} | |
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 context | |
id: context | |
run: | | |
#!/bin/bash | |
set -x # TODO: remove after debug | |
# Create temporary files | |
PRS_DATA_FILE=$(mktemp) | |
PR_DATA_FILE=$(mktemp) | |
ARTIFACTS_DATA_FILE=$(mktemp) | |
# Search for PR using the commit SHA and extract all required information | |
curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ | |
"${GITHUB_API_URL}/search/issues?q=${INPUT_HEAD_SHA}+repo:${INPUT_BASE_REPOSITORY}+is:pr+is:open" >"$PRS_DATA_FILE" | |
PR_NUMBER=$(jq -r '.items[0].number' "$PRS_DATA_FILE") | |
curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ | |
"${GITHUB_API_URL}/repos/${INPUT_BASE_REPOSITORY}/pulls/${PR_NUMBER}" >"$PR_DATA_FILE" | |
MERGE_COMMIT_SHA=$(jq -r '.merge_commit_sha' "$PR_DATA_FILE") | |
HEAD_REPO_OWNER=$(jq -r '.head.repo.owner.login' "$PR_DATA_FILE") | |
HEAD_REPO_NAME=$(jq -r '.head.repo.name' "$PR_DATA_FILE") | |
HEAD_BRANCH=$(jq -r '.head.ref' "$PR_DATA_FILE") | |
# Search for the image tag in GHCR | |
IMAGE_NAME="${INPUT_BASE_REPOSITORY}" | |
IMAGE_TAG="${MERGE_COMMIT_SHA}" | |
if IMAGE_DIGEST=$(skopeo inspect \ | |
--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" | |
curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ | |
"${GITHUB_API_URL}/repos/${INPUT_BASE_REPOSITORY}/actions/runs/${INPUT_WORKFLOW_RUN_ID}/artifacts" >"$ARTIFACTS_DATA_FILE" | |
ARTIFACT_AVAILABLE=$(jq --arg name "$ARTIFACT_NAME" '.artifacts | any(.name == $name and .expired == false)' "$ARTIFACTS_DATA_FILE") | |
# Clean up temporary files | |
rm -f "$PRS_DATA_FILE" "$PR_DATA_FILE" "$ARTIFACTS_DATA_FILE" | |
# 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, cannot proceed. Run the build workflow first" | |
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 }} | |
- name: Download Artifact from Previous Workflow Run | |
if: ${{ steps.context.outputs.image_available == 'false' && steps.context.outputs.artifact_available == 'true' }} | |
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 | |
with: | |
name: ${{ steps.context.outputs.artifact_name }} | |
path: /tmp | |
run-id: ${{ steps.context.outputs.workflow_run_id }} | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Copy Container Image from Artifact to GHCR | |
if: ${{ steps.context.outputs.image_available == 'false' && steps.context.outputs.artifact_available == 'true' }} | |
id: copy | |
run: | | |
#!/bin/bash | |
set -x # TODO: remove after debug | |
if [ -f "$INPUT_ARTIFACT_FILE" ]; then | |
docker load --input "$INPUT_ARTIFACT_FILE" | |
else | |
echo "::error::Artifact file not found" | |
exit 1 | |
fi | |
TARGET_IMAGE_NAME="${INPUT_IMAGE_NAME}" # TODO: add `test` suffix to the image name to avoid conflicts with the main image | |
TARGET_IMAGE_TAG="${INPUT_IMAGE_TAG}" | |
if skopeo copy \ | |
docker-archive:${INPUT_ARTIFACT_FILE} \ | |
docker://ghcr.io/${TARGET_IMAGE_NAME}:${TARGET_IMAGE_TAG}; then | |
echo "image_available=true" >>$GITHUB_OUTPUT | |
echo "image_name=${TARGET_IMAGE_NAME}" >>$GITHUB_OUTPUT | |
echo "image_tag=${TARGET_IMAGE_TAG}" >>$GITHUB_OUTPUT | |
else | |
echo "::error::Failed to copy image to GHCR" | |
exit 1 | |
fi | |
env: | |
INPUT_ARTIFACT_FILE: /tmp/${{ steps.context.outputs.artifact_name }}.tar | |
INPUT_IMAGE_NAME: ${{ steps.context.outputs.image_name }} | |
INPUT_IMAGE_TAG: ${{ steps.context.outputs.image_tag }} | |
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: | |
if: ${{ needs.prepare.outputs.image_available == 'true' || needs.prepare.outputs.artifact_available == 'true' }} | |
runs-on: ubuntu-latest | |
permissions: | |
packages: read | |
contents: read | |
needs: | |
- prepare | |
- plan | |
environment: | |
name: ${{ needs.plan.outputs.environment_name }} | |
env: | |
INPUT_IMAGE_NAME: ${{ needs.prepare.outputs.image_name }} | |
INPUT_IMAGE_TAG: ${{ needs.prepare.outputs.image_tag }} | |
steps: | |
- name: Log in to the Container registry # TODO: remove after debug | |
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Load Container Image from GHCR # TODO: remove after debug | |
if: ${{ needs.prepare.outputs.image_available == 'true' }} | |
run: | | |
docker pull ghcr.io/${INPUT_IMAGE_NAME}:${INPUT_IMAGE_TAG} | |
docker inspect ghcr.io/${INPUT_IMAGE_NAME}:${INPUT_IMAGE_TAG} | |
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
ref: ${{ needs.prepare.outputs.merge_commit_sha }} | |
lfs: true | |
persist-credentials: false |