Skip to content

Conversation

@rmgpinto
Copy link
Collaborator

closes https://linear.app/ghost/issue/AP-976

  • Added ephemeral staging environments

@coderabbitai
Copy link

coderabbitai bot commented Mar 24, 2025

Walkthrough

This pull request updates the GitHub Actions workflow configuration file by renaming the workflow from "CI" to "CICD" and refining the pull_request trigger to respond only to specific actions: opened, synchronize, reopened, labeled, and unlabeled. Permissions are extended to include read access for pull-requests. The build-test-push job's environment is renamed from "staging" to "build", and steps involving GCP authentication, Artifact Registry login, and Docker image pushing are conditionally executed only for pull_request events with the specified actions. A new deploy-pr job is added to deploy ephemeral staging environments when a pull request label matches the pattern "*.ghost.is". This job performs label checking, checks out two repositories, sets up Terraform with a version read from a file, modifies Terraform module URLs and backend prefixes, authenticates with GCP, runs Terraform init and apply, deploys migrations to Cloud Run, and updates a GCP load balancer URL map to route traffic to the ephemeral environment. The deploy-staging and deploy-production jobs remain but have their environment declarations removed.

Possibly related PRs

  • Added production cicd #473: Both PRs modify GitHub Actions workflows to enhance CICD processes, specifically adding or refining deployment jobs for staging and production environments, indicating a direct relation in managing deployment pipelines.

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb6739c and e33a7ae.

📒 Files selected for processing (1)
  • .github/workflows/cicd.yml (5 hunks)
🔇 Additional comments (5)
.github/workflows/cicd.yml (5)

51-51: Confirm environment name change is intentional.

The environment for build-test-push is now set to build (was previously staging). Ensure this aligns with your deployment and access control requirements, as environment names can affect secrets and environment protection rules.


108-139: Conditional GCP and Docker steps: robust and correct.

The conditional execution of GCP authentication, Artifact Registry login, and Docker image push steps for specific pull request actions is correct and prevents unnecessary operations. This improves security and efficiency.


148-274: Ephemeral staging deploy: robust, modular, and secure.

The deploy-pr job is well-structured:

  • Label check logic is robust (-n "$LABEL_NAMES").
  • All steps are gated on the label match output.
  • Uses actions/checkout@v4 for both infra and terraform repos (addresses previous security advisories).
  • Terraform version is dynamically read and used.
  • GCP authentication uses a dedicated service account for staging environments.
  • Load balancer update script uses set -euo pipefail and cleans up temp files, addressing past review feedback.
  • Route rule YAML structure is correct.
  • Secrets are referenced securely.

No critical issues found. The job is modular, maintainable, and follows best practices.


243-273: Shell script: error handling and cleanup are robust.

The load balancer update script includes set -euo pipefail and uses mv to atomically update config files. Temporary files are cleaned up, and the script is clear and maintainable. All past review feedback on error handling and YAML correctness is addressed.


275-389: No issues with deploy-staging and deploy-production jobs.

These jobs remain unchanged except for the removal of environment declarations. The steps are standard for GCP Cloud Run deployments and use secure authentication and secret handling.


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🔭 Outside diff range comments (1)
.github/workflows/deploy.yml (1)

97-103: ⚠️ Potential issue

Critical Issue: Undefined Output in Deploy-Old for ActivityPub API

Finally, the "Deploy ActivityPub API to Cloud Run" step in the deploy-old job references the same undefined output. To ensure proper image deployment, update this reference to correctly obtain the intended version information from the CI workflow.

🧰 Tools
🪛 actionlint (1.7.4)

100-100: property "build-test-push" is not defined in object type {}

(expression)

🧹 Nitpick comments (1)
.github/workflows/deploy.yml (1)

10-33: Deploy Ephemeral Staging: Variable Usage & Environment Naming

The ephemeral staging job properly handles Google Cloud authentication and checks if the infrastructure is already provisioned. Two points to consider:

  1. Variable Availability: The command uses GITHUB_HEAD_REF to filter services. Since workflow_run contexts may not always populate this variable (which is more typical in pull request events), please verify its availability or consider an alternative identifier.
  2. Environment Naming: The job is configured with environment: build. In the context of ephemeral staging, a more descriptive name (e.g., ephemeral-staging) might improve clarity in your deployment logs and reports.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 037b8fc and 07388f2.

📒 Files selected for processing (2)
  • .github/workflows/build.yml (1 hunks)
  • .github/workflows/deploy.yml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.4)
.github/workflows/deploy.yml

52-52: property "build-test-push" is not defined in object type {}

(expression)


60-60: property "build-test-push" is not defined in object type {}

(expression)


67-67: property "build-test-push" is not defined in object type {}

(expression)


85-85: property "build-test-push" is not defined in object type {}

(expression)


93-93: property "build-test-push" is not defined in object type {}

(expression)


100-100: property "build-test-push" is not defined in object type {}

(expression)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build, Test and Push
🔇 Additional comments (2)
.github/workflows/build.yml (1)

6-11: Enhanced Pull Request Event Triggers

The addition of specific pull request event types (opened, synchronize, reopened, labeled, and unlabeled) improves the granularity of workflow triggers for PR events. This should help ensure that changes are properly tested during development.

.github/workflows/deploy.yml (1)

1-8: Solid Setup for the New Deployment Workflow

The workflow is clearly set up to trigger on workflow_run for the "CI" workflow with the completed type. This ensures that the deployment process only begins after the CI process finishes. It would be beneficial to document in your repository how the outputs from the CI workflow (like the image version tags) are expected to be passed along, as they are referenced later in the file.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

🔭 Outside diff range comments (1)
.github/workflows/deploy.yml (1)

85-117: ⚠️ Potential issue

Deploy-Old Job: Missing Dependency Declaration
Similarly, the "deploy-old" job uses outputs from the ci-docker-tags job without declaring a dependency on it. This can result in undefined outputs during execution. To ensure that the necessary data is available, add the dependency like so:

-    runs-on: ubuntu-latest
+    needs: [ci-docker-tags]
+    runs-on: ubuntu-latest
🧰 Tools
🪛 actionlint (1.7.4)

99-99: property "ci-docker-tags" is not defined in object type {}

(expression)


107-107: property "ci-docker-tags" is not defined in object type {}

(expression)


114-114: property "ci-docker-tags" is not defined in object type {}

(expression)

🧹 Nitpick comments (1)
.github/workflows/deploy.yml (1)

9-23: CI Docker Tags Job: Output Extraction
The ci-docker-tags job correctly downloads the docker_tags artifact and extracts the Docker tag values for activitypub and migrations. Consider adding error handling or a check to ensure that docker_tags.txt exists and contains the expected content; this would help avoid unexpected failures in subsequent deployment jobs if the artifact is missing or malformed.

🛑 Comments failed to post (1)
.github/workflows/deploy.yml (1)

48-84: ⚠️ Potential issue

Deploy-Staging Job: Missing Dependency Declaration
This job references outputs from the ci-docker-tags job using expressions such as ${{ needs.ci-docker-tags.outputs.migrations_docker_tags }} and ${{ needs.ci-docker-tags.outputs.activitypub_docker_tags }}. However, there is no dependency declared using the needs: keyword, which means these outputs may not be available and could lead to runtime errors. To fix this, add the dependency to ensure that the ci-docker-tags job completes before this job starts. For example:

-    name: (staging) Deploy
+    needs: [ci-docker-tags]
+    name: (staging) Deploy
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

  deploy-staging:
    if: github.ref == 'refs/heads/main'
    needs: [ci-docker-tags]
    name: (staging) Deploy
    environment: build
    runs-on: ubuntu-latest
    strategy:
      matrix:
        region: [europe-west4, europe-west3]
    steps:
      - name: "Auth with Google Cloud"
        uses: 'google-github-actions/auth@v2'
        with:
          credentials_json: ${{ secrets.SERVICE_ACCOUNT_KEY }}

      - name: "Deploy Migrations to Cloud Run"
        if: ${{ matrix.region == 'europe-west4' }}
        uses: 'google-github-actions/deploy-cloudrun@v2'
        with:
          image: europe-docker.pkg.dev/ghost-activitypub/activitypub/migrations:${{ needs.ci-docker-tags.outputs.migrations_docker_tags }}
          region: ${{ matrix.region }}
          job: stg-${{ matrix.region }}-activitypub-migrations
          flags: '--wait --execute-now --set-cloudsql-instances=ghost-activitypub:${{ matrix.region }}:stg-${{ matrix.region }}-activitypub-primary'

      - name: "Deploy ActivityPub Queue to Cloud Run"
        uses: 'google-github-actions/deploy-cloudrun@v2'
        with:
          image: europe-docker.pkg.dev/ghost-activitypub/activitypub/activitypub:${{ needs.ci-docker-tags.outputs.activitypub_docker_tags }}
          region: ${{ matrix.region }}
          service: stg-${{ matrix.region }}-activitypub-queue

      - name: "Deploy ActivityPub API to Cloud Run"
        uses: 'google-github-actions/deploy-cloudrun@v2'
        with:
          image: europe-docker.pkg.dev/ghost-activitypub/activitypub/activitypub:${{ needs.ci-docker-tags.outputs.activitypub_docker_tags }}
          region: ${{ matrix.region }}
          service: stg-${{ matrix.region }}-activitypub-api
🧰 Tools
🪛 actionlint (1.7.4)

66-66: property "ci-docker-tags" is not defined in object type {}

(expression)


74-74: property "ci-docker-tags" is not defined in object type {}

(expression)


81-81: property "ci-docker-tags" is not defined in object type {}

(expression)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🔭 Outside diff range comments (1)
.github/workflows/deploy.yml (1)

85-117: ⚠️ Potential issue

Deploy-Old Job – Ensure Consistent Image Tag References
Similarly, the deploy-old job references outputs from the ci-docker-tags job (e.g., ${{ needs.ci-docker-tags.outputs.migrations_docker_tags }}). This setup is dependent on the proper declaration of job outputs in the ci-docker-tags job. Once the outputs are defined at the job level, these references should resolve correctly.

🧰 Tools
🪛 actionlint (1.7.4)

99-99: property "ci-docker-tags" is not defined in object type {}

(expression)


107-107: property "ci-docker-tags" is not defined in object type {}

(expression)


114-114: property "ci-docker-tags" is not defined in object type {}

(expression)

🧹 Nitpick comments (1)
.github/workflows/build.yml (1)

99-101: Commented Out Test Step – Verify Intentional Disablement
The "Run Tests" step has been commented out. If this is an intentional decision (perhaps because tests are handled elsewhere or temporarily disabled during staging deployments), please add an inline comment explaining the rationale to avoid confusion in the future.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d6970c0 and 623a891.

📒 Files selected for processing (2)
  • .github/workflows/build.yml (3 hunks)
  • .github/workflows/deploy.yml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.4)
.github/workflows/deploy.yml

66-66: property "ci-docker-tags" is not defined in object type {}

(expression)


74-74: property "ci-docker-tags" is not defined in object type {}

(expression)


81-81: property "ci-docker-tags" is not defined in object type {}

(expression)


99-99: property "ci-docker-tags" is not defined in object type {}

(expression)


107-107: property "ci-docker-tags" is not defined in object type {}

(expression)


114-114: property "ci-docker-tags" is not defined in object type {}

(expression)

🔇 Additional comments (3)
.github/workflows/build.yml (2)

6-11: Enhanced Pull Request Trigger Events
The addition of the extra pull_request event types (opened, synchronize, reopened, labeled, unlabeled) broadens the scope of events triggering this workflow. This ensures that changes affecting PR metadata are caught early.


130-139: Output and Upload Docker Tags Steps Added
The new steps to output Docker tags to a file and subsequently upload them as an artifact correctly support the new CD workflow. Ensure that the file path and artifact name remain consistent with what the deployment workflow expects.

.github/workflows/deploy.yml (1)

1-8: Continuous Deployment Workflow Trigger Configuration
The CD workflow is now configured to trigger on the completion of the CI workflow via workflow_run. This setup is well suited to ensure that deployment steps run only after CI completes successfully.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
.github/workflows/cicd.yml (1)

163-163: ⚠️ Potential issue

Quote shell variables in conditional checks for robustness

In the label check step, the conditional if [ $LABEL_NAMES != "" ]; should quote the variable to prevent errors if $LABEL_NAMES is unset or contains spaces. Use [ -n "$LABEL_NAMES" ] for a safe, POSIX-compliant check.

- if [ $LABEL_NAMES != "" ]; then
+ if [ -n "$LABEL_NAMES" ]; then

This prevents unbound variable errors and improves script reliability.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9b24484 and bb6739c.

📒 Files selected for processing (1)
  • .github/workflows/cicd.yml (5 hunks)
🧰 Additional context used
🪛 actionlint (1.7.4)
.github/workflows/cicd.yml

173-173: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


181-181: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build, Test and Push
🔇 Additional comments (3)
.github/workflows/cicd.yml (3)

245-275: Excellent: Load balancer update script is robust and follows best practices

The load balancer update step now includes proper error handling, atomic file operations, and re-imports the modified config. Temporary files are managed and the logic is clear. This addresses all previously raised concerns.


109-140: Conditional Docker push logic is correct and efficient

The conditional execution of GCP authentication, Artifact Registry login, and Docker image pushes ensures that these steps only run for relevant pull request actions. This optimizes workflow runs and avoids unnecessary operations.


149-243: Ephemeral staging deployment logic is well-structured

The new deploy-pr job is well-organized, with clear separation of label checking, repo checkouts, Terraform setup, GCP authentication, and deployment steps. The use of environment variables and conditional execution is appropriate.

🧰 Tools
🪛 actionlint (1.7.4)

173-173: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


181-181: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds ephemeral staging environments by updating the CICD workflow triggers, modifying job environments, and introducing a new deploy-pr job to conditionally deploy based on pull request labels.

  • Updated pull request event types and conditions in the workflow.
  • Changed the build-test-push job’s environment from "staging" to "build".
  • Added a deploy-pr job with label checking and load balancer updates for ephemeral staging.

run: |
export LABEL_NAMES=$(echo "$LABELS" | jq -r '[.[] | select(.name | test("\\.ghost\\.is$")) | .name] | join(",")')
echo "Label names: $LABEL_NAMES"
if [ $LABEL_NAMES != "" ]; then
Copy link

Copilot AI Apr 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider quoting $LABEL_NAMES (e.g. if [ "$LABEL_NAMES" != "" ]; then) to prevent word splitting or potential errors when the variable is empty.

Suggested change
if [ $LABEL_NAMES != "" ]; then
if [ "$LABEL_NAMES" != "" ]; then

Copilot uses AI. Check for mistakes.
export PR_SERVICE="https://www.googleapis.com/compute/v1/projects/ghost-activitypub/global/backendServices/stg-pr-${{ github.event.pull_request.number }}-api"
# Add host rules and path matchers if they don't exist
yq '.hostRules = (.hostRules // [{"hosts": ["activitypub.infra.ghost.is"], "pathMatcher": "staging-environments"}])' config.yml > config.yml.tmp
yq '.hostRules = ([{"hosts": ["activitypub.infra.ghost.is"], "pathMatcher": "staging-environments"}])' config.yml > config.yml.tmp
Copy link

Copilot AI Apr 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .hostRules field is being set consecutively (lines 258 and 259); if the duplication is not intentional, please remove the redundant command to avoid unexpected overwrites.

Suggested change
yq '.hostRules = ([{"hosts": ["activitypub.infra.ghost.is"], "pathMatcher": "staging-environments"}])' config.yml > config.yml.tmp

Copilot uses AI. Check for mistakes.
build-test-push:
name: Build, Test and Push
environment: staging
environment: build
Copy link

Copilot AI Apr 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The build-test-push job’s environment was changed from 'staging' to 'build'. Please confirm that this alteration is intentional and does not inadvertently affect deployment behavior.

Suggested change
environment: build
environment: staging

Copilot uses AI. Check for mistakes.
closes https://linear.app/ghost/issue/AP-976

- Create ephemeral staging environment on PR labels *.ghost.is
@rmgpinto rmgpinto force-pushed the ephemeral-staging-envs branch from 02d8c6b to e33a7ae Compare April 16, 2025 13:06
@rmgpinto rmgpinto merged commit 1e2a39c into main Apr 16, 2025
7 checks passed
@rmgpinto rmgpinto deleted the ephemeral-staging-envs branch April 16, 2025 13:20
vershwal pushed a commit that referenced this pull request Apr 16, 2025
closes https://linear.app/ghost/issue/AP-976

- Create ephemeral staging environment on PR labels *.ghost.is
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants