name: Pull Request Docs Draft on: pull_request: branches: - '**' paths: - 'docs/**' - '.github/workflows/deploy-docs-draft.yml' concurrency: group: ${{ github.workflow }}-${{ github.ref }} jobs: build-and-deploy: runs-on: ubuntu-latest steps: - name: Checkout Repository uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 18 cache: yarn cache-dependency-path: ./docs/yarn.lock - name: Validate Branch Names run: | # Check if branch names contain invalid characters. Only alphanumeric, _, -, ., and / are allowed. validate_branch_name() { local branch_name="$1" if [[ ! "$branch_name" =~ ^[a-zA-Z0-9/_\.-]+$ ]]; then echo "Error: Branch name contains invalid characters. Only alphanumeric, _, -, ., and / are allowed." exit 1 fi } validate_branch_name "${{ github.event.pull_request.head.ref }}" - name: Extract Branch Names id: extract_branch run: | # Extract and transform branch names extract_branch() { local input_branch="$1" # Check if input_branch starts with "refs/heads/" if [[ "$input_branch" == refs/heads/* ]]; then # Remove "refs/heads/" prefix safely using parameter expansion branch_name="${input_branch#refs/heads/}" echo "$branch_name" else echo "$input_branch" fi } # Transform branch names in form of `refs/heads/main` to `main` draft_branch=$(extract_branch "${{ github.event.pull_request.head.ref }}") # Replace / with - in the draft branch name to use as a directory name draft_directory=$(echo "$draft_branch" | tr / -) # Safe echo to $GITHUB_OUTPUT { echo "draft_branch=$draft_branch" echo "draft_directory=$draft_directory" } >> "$GITHUB_OUTPUT" - name: Set Draft URL id: draft_url if: success() run: | echo "url=${{ vars.DOCS_DRAFT_BASE_URL }}/langflow-drafts/${{ steps.extract_branch.outputs.draft_directory }}/index.html" >> $GITHUB_OUTPUT - name: Install dependencies run: cd docs && yarn install - name: Build website if: success() run: | set -o pipefail cd docs yarn build |& tee $GITHUB_WORKSPACE/build.log env: BASE_URL: /langflow-drafts/${{ steps.extract_branch.outputs.draft_directory }} FORCE_COLOR: 0 # Disable color output - name: Check Build Result id: buildLogFail if: failure() run: | MULTILINE_LOG=$(cat $GITHUB_WORKSPACE/build.log) echo "BUILD_FAILURE<> $GITHUB_ENV echo $MULTILINE_LOG >> $GITHUB_ENV echo "EOF" >> $GITHUB_ENV - name: Assemble Build Success Comment if: success() run: | build_success_comment="Build successful! :white_check_mark:" build_success_comment+="\nDeploying docs draft." echo "BUILD_SUCCESS_COMMENT<> $GITHUB_ENV echo -e "$build_success_comment" >> $GITHUB_ENV echo "EOF" >> $GITHUB_ENV - name: Create Build Success Comment if: success() uses: peter-evans/create-or-update-comment@v4 with: issue-number: ${{ github.event.pull_request.number }} body: "${{ env.BUILD_SUCCESS_COMMENT }}" reactions: rocket - name: Create Build Failure Comment if: failure() uses: peter-evans/create-or-update-comment@v4 with: issue-number: ${{ github.event.pull_request.number }} body: | Build failure! :x: > ${{ env.BUILD_FAILURE }} reactions: confused - name: Find Comment id: fc if: success() uses: peter-evans/find-comment@v3 with: issue-number: ${{ github.event.pull_request.number }} body-includes: Build successful! direction: last - name: Configure AWS CLI if: success() run: | aws configure set aws_access_key_id ${{ secrets.DOCS_AWS_ACCESS_KEY_ID }} aws configure set aws_secret_access_key ${{ secrets.DOCS_AWS_SECRET_ACCESS_KEY }} aws configure set region us-west-2 - name: Deploy to S3 if: success() run: | set -o pipefail cd docs mkdir langflow-drafts mv build langflow-drafts/${{ steps.extract_branch.outputs.draft_directory }} cd langflow-drafts s3_params=( # Hide upload progress for a cleaner sync log --no-progress # Because the build will produce new timestamps # on each build, sync files based on size. --size-only --delete --exclude "*" --include "${{ steps.extract_branch.outputs.draft_directory }}/*" ) echo "Deploying draft to S3." |& tee -a $GITHUB_WORKSPACE/deploy.log echo "aws s3 sync . s3://${{ vars.DOCS_DRAFT_S3_BUCKET_NAME }}/langflow-drafts ${s3_params[@]}" |& tee -a $GITHUB_WORKSPACE/deploy.log aws s3 sync . "s3://${{ vars.DOCS_DRAFT_S3_BUCKET_NAME }}/langflow-drafts" "${s3_params[@]}" |& tee -a $GITHUB_WORKSPACE/deploy.log - name: Invalidate CloudFront Cache if: success() run: | invalidation_batch="{ \"Paths\": { \"Quantity\": 1, \"Items\": [\"/langflow-drafts/${{ steps.extract_branch.outputs.draft_directory }}/*\"] }, \"CallerReference\": \"langflow-docs-draft-files-$(date +%s)\" }" echo $invalidation_batch | jq . |& tee -a "$GITHUB_WORKSPACE/deploy.log" echo "Creating invalidation." |& tee -a "$GITHUB_WORKSPACE/deploy.log" invalidation_id=$(aws cloudfront create-invalidation --distribution-id "${{ vars.DOCS_DRAFT_CLOUD_FRONT_DISTRIBUTION_ID }}" --invalidation-batch "$invalidation_batch" --query 'Invalidation.Id' --output text |& tee -a "$GITHUB_WORKSPACE/deploy.log") echo "Awaiting invalidation." |& tee -a "$GITHUB_WORKSPACE/deploy.log" aws cloudfront wait invalidation-completed --distribution-id "${{ vars.DOCS_DRAFT_CLOUD_FRONT_DISTRIBUTION_ID }}" --id "$invalidation_id" |& tee -a "$GITHUB_WORKSPACE/deploy.log" echo "Invalidation complete." |& tee -a "$GITHUB_WORKSPACE/deploy.log" - name: Update Comment if: ${{ steps.fc.outputs.comment-id != '' }} uses: peter-evans/create-or-update-comment@v4 with: comment-id: ${{ steps.fc.outputs.comment-id }} body: | Deploy successful! [View draft](${{ steps.draft_url.outputs.url }}) reactions: hooray - name: Upload Deploy Log uses: actions/upload-artifact@v4 if: always() with: name: deploy.log path: ${{ github.workspace }}/deploy.log