PR Environment Deploy #41
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 # 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 \ | |
--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" | |
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 }} | |
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: | |
actions: read # Needed to access artifacts | |
packages: write # To push to GHCR | |
contents: read | |
needs: | |
- prepare | |
- plan | |
environment: | |
name: ${{ needs.plan.outputs.environment_name }} | |
env: | |
INPUT_ARTIFACT_NAME: ${{ needs.prepare.outputs.artifact_name }} | |
INPUT_ARTIFACT_FILE: /tmp/${{ needs.prepare.outputs.artifact_name }}.tar | |
INPUT_IMAGE_NAME: ${{ needs.prepare.outputs.image_name }} | |
INPUT_IMAGE_TAG: ${{ needs.prepare.outputs.image_tag }} | |
steps: | |
- 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: 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} | |
- name: Download Artifact from Previous Workflow Run | |
if: ${{ needs.prepare.outputs.image_available == 'false' && needs.prepare.outputs.artifact_available == 'true' }} | |
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 | |
with: | |
name: ${{ env.INPUT_ARTIFACT_NAME }} | |
path: /tmp | |
run-id: ${{ needs.prepare.outputs.workflow_run_id }} | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Load Container Image from Artifact | |
if: ${{ needs.prepare.outputs.image_available == 'false' && needs.prepare.outputs.artifact_available == 'true' }} | |
id: load_image | |
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 | |
- name: List and Inspect Container Images # TODO: remove after debug | |
run: | | |
docker images ls | |
docker inspect ghcr.io/${INPUT_IMAGE_NAME}:${INPUT_IMAGE_TAG} | |
- name: Push Container Image to GHCR | |
if: ${{ needs.prepare.outputs.image_available == 'false' && needs.prepare.outputs.artifact_available == 'true' }} | |
run: | | |
skopeo copy \ | |
docker-archive:${INPUT_ARTIFACT_FILE} \ | |
docker://ghcr.io/${INPUT_IMAGE_NAME}:${INPUT_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 |