More explicit handling of carriage return logs in steps #302
Workflow file for this run
This file contains hidden or 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 Workspace Deploy | |
on: | |
pull_request: | |
types: [opened, synchronize] | |
workflow_dispatch: | |
inputs: | |
branch: | |
description: Branch to checkout and deploy | |
required: true | |
type: string | |
concurrency: | |
# New commit on branch cancels running workflows of the same branch | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: true | |
env: | |
ZENML_ANALYTICS_OPT_IN: false | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
jobs: | |
check-label: | |
runs-on: ubuntu-latest | |
if: github.event_name == 'pull_request' && github.event.pull_request.draft == | |
false | |
outputs: | |
should_deploy: ${{ steps.check-label.outputs.has_label }} | |
steps: | |
# using this instead of contains(github.event.pull_request.labels.*.name, 'staging-workspace') | |
# to make it dynamic, otherwise github context is fixed at the moment of trigger event. | |
# With dynamic approach dev can set label and rerun this flow to make it running. | |
- name: Get PR labels | |
id: pr-labels | |
uses: actions/[email protected] | |
with: | |
script: | | |
const prNumber = ${{ github.event.pull_request.number }}; | |
const { data: labels } = await github.rest.issues.listLabelsOnIssue({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: prNumber, | |
}); | |
const labelNames = labels.map(label => label.name); | |
core.setOutput('all-labels', labelNames.join(',')); | |
- name: Check if staging-workspace label is set | |
id: check-label | |
run: | | |
if [[ "${{ contains(steps.pr-labels.outputs.all-labels, 'staging-workspace') }}" == "true" ]]; then | |
echo "Label 'staging-workspace' found, will deploy workspace" | |
echo "has_label=true" >> $GITHUB_OUTPUT | |
else | |
echo "Label 'staging-workspace' not found, skipping workspace deployment" | |
echo "has_label=false" >> $GITHUB_OUTPUT | |
fi | |
set-branch-info: | |
needs: check-label | |
if: github.event_name == 'workflow_dispatch' || needs.check-label.outputs.should_deploy | |
== 'true' | |
runs-on: ubuntu-latest | |
outputs: | |
branch_name: ${{ steps.slugify-branch.outputs.branch_slug }} # Docker-compatible tag | |
original_branch: ${{ steps.determine-branch.outputs.branch }} # Original branch name | |
zenml_version: ${{ steps.get-version.outputs.zenml_version }} # ZenML version | |
steps: | |
- name: Determine branch to use | |
id: determine-branch | |
run: | | |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then | |
# For PR use the head ref (PR branch) | |
echo "branch=${{ github.head_ref }}" >> $GITHUB_OUTPUT | |
else | |
# For manual trigger, use the provided branch | |
echo "branch=${{ github.event.inputs.branch }}" >> $GITHUB_OUTPUT | |
fi | |
- name: Checkout repository with correct branch | |
uses: actions/[email protected] | |
with: | |
ref: ${{ steps.determine-branch.outputs.branch }} | |
fetch-depth: 0 | |
- name: Slugify branch name | |
id: slugify-branch | |
run: | | |
# Create a Docker-compatible tag from branch name | |
BRANCH_NAME="${{ steps.determine-branch.outputs.branch }}" | |
# 1. Convert to lowercase | |
# 2. Replace invalid chars with dashes | |
# 3. Remove leading non-alphanumeric chars (Docker tags must start with a letter or number) | |
# 4. Replace multiple consecutive dashes with a single dash | |
# 5. Remove trailing dashes (Docker tags can't end with a dash) | |
# 6. Limit to 128 chars max (Docker's limit) | |
BRANCH_SLUG=$(echo "$BRANCH_NAME" | \ | |
tr '[:upper:]' '[:lower:]' | \ | |
tr -c 'a-z0-9_.-' '-' | \ | |
sed -E 's/^[^a-z0-9]*//' | \ | |
sed -E 's/-+/-/g' | \ | |
sed -E 's/-$//' | \ | |
cut -c 1-128) | |
# If we end up with an empty string (unlikely but possible), use "dev" as fallback | |
if [ -z "$BRANCH_SLUG" ]; then | |
BRANCH_SLUG="dev" | |
fi | |
echo "Created Docker-compatible tag: $BRANCH_SLUG" | |
echo "branch_slug=${BRANCH_SLUG}" >> $GITHUB_OUTPUT | |
- name: Get ZenML version | |
id: get-version | |
run: | | |
# Get ZenML version from src/zenml/VERSION file | |
if [ -f "src/zenml/VERSION" ]; then | |
# Read the version but remove any whitespace | |
ZENML_VERSION=$(cat src/zenml/VERSION | tr -d '[:space:]') | |
echo "Version detected: ${ZENML_VERSION}" | |
echo "zenml_version=${ZENML_VERSION}" >> $GITHUB_OUTPUT | |
else | |
echo "ERROR: VERSION file not found at src/zenml/VERSION" | |
echo "This is required for deployment. Please ensure you're using a valid branch." | |
exit 1 | |
fi | |
build-images: | |
needs: [set-branch-info, check-label] | |
if: always() && (github.event_name == 'workflow_dispatch' || needs.check-label.outputs.should_deploy | |
== 'true') && needs.set-branch-info.result == 'success' | |
runs-on: ubuntu-latest | |
permissions: | |
contents: read | |
id-token: write | |
steps: | |
- name: Checkout code | |
uses: actions/[email protected] | |
with: | |
ref: ${{ needs.set-branch-info.outputs.original_branch }} | |
# Sign in to Google | |
- uses: google-github-actions/setup-gcloud@v0 | |
with: | |
service_account_email: ${{ secrets.GCP_CLOUDBUILD_EMAIL }} | |
service_account_key: ${{ secrets.GCP_CLOUDBUILD_KEY }} | |
project_id: ${{ secrets.GCP_CLOUDBUILD_PROJECT }} | |
# Submit the Cloudbuild job | |
- name: Build docker images | |
run: | | |
gcloud builds submit \ | |
--quiet \ | |
--config=pull_request_cloudbuild.yaml \ | |
--substitutions=_ZENML_BRANCH_NAME=${{ needs.set-branch-info.outputs.branch_name }} | |
manage-tenant: | |
needs: [build-images, set-branch-info] | |
if: always() && needs.build-images.result == 'success' | |
runs-on: ubuntu-latest | |
env: | |
ZENML_VERSION: ${{ needs.set-branch-info.outputs.zenml_version }} | |
steps: | |
- name: Checkout code | |
uses: actions/[email protected] | |
with: | |
ref: ${{ needs.set-branch-info.outputs.original_branch }} | |
- name: Set up Python | |
uses: actions/[email protected] | |
with: | |
python-version: '3.11' | |
- name: Install dependencies | |
run: | | |
python -m pip install --upgrade pip | |
pip install requests | |
- name: Manage workspace | |
env: | |
CLOUD_STAGING_CLIENT_ID: ${{ secrets.CLOUD_STAGING_CLIENT_ID }} | |
CLOUD_STAGING_CLIENT_SECRET: ${{ secrets.CLOUD_STAGING_CLIENT_SECRET }} | |
CLOUD_STAGING_GH_ACTIONS_ORGANIZATION_ID: ${{ secrets.CLOUD_STAGING_GH_ACTIONS_ORGANIZATION_ID }} | |
WORKSPACE_NAME_OR_ID: ${{ needs.set-branch-info.outputs.branch_name }} | |
DOCKER_IMAGE: zenmldocker/zenml-server-dev:${{ needs.set-branch-info.outputs.branch_name }} | |
ZENML_VERSION: ${{ env.ZENML_VERSION }} | |
run: python scripts/manage_workspace.py | |
- name: Set tenant URL | |
run: echo "TENANT_URL=https://staging.cloud.zenml.io/workspaces/${{ needs.set-branch-info.outputs.branch_name }}/projects" | |
>> $GITHUB_ENV | |
- name: Check if deployment comment exists | |
id: check-comment | |
if: github.event_name == 'pull_request' | |
run: | | |
# Search for comments containing the workspace URL | |
COMMENT_COUNT=$(gh pr view ${{ github.event.pull_request.number }} --json comments --jq '.comments[].body | select(contains("Branch tenant has been deployed"))' | wc -l) | |
if [ "$COMMENT_COUNT" -gt 0 ]; then | |
echo "has_comment=true" >> $GITHUB_OUTPUT | |
else | |
echo "has_comment=false" >> $GITHUB_OUTPUT | |
fi | |
- name: Add comment with tenant URL (PR) | |
if: github.event_name == 'pull_request' && steps.check-comment.outputs.has_comment | |
== 'false' | |
run: |- | |
gh pr comment ${{ github.event.pull_request.number }} --body "✅ Branch tenant has been deployed! Access it at: ${{ env.TENANT_URL }}" | |
- name: Output tenant URL (Manual) | |
if: github.event_name == 'workflow_dispatch' | |
run: |- | |
echo "✅ Branch tenant has been deployed! Access it at: ${{ env.TENANT_URL }}" |