Skip to content

Conversation

@kwon204
Copy link
Contributor

@kwon204 kwon204 commented Mar 17, 2025

#️⃣ 연관된 이슈>

📝 작업 내용> 이번 PR에서 작업한 내용을 간략히 설명해주세요(이미지 첨부 가능)

  • frontend nginx.conf 추가
  • 추가한 nginx.conf 파일을 ec2로 옮기기 위한 코드 추가

🙏 여기는 꼭 봐주세요! > 리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

Summary by CodeRabbit

  • New Features

    • Introduced automated deployment scripts for both frontend and backend applications, incorporating health checks and rollback procedures to ensure a smoother update experience.
    • Enhanced server configurations to enforce secure HTTPS connections and optimized API request handling for improved service reliability.
  • Chores

    • Updated deployment workflows with additional file transfer and environment standardization steps, streamlining the continuous delivery process.

@kwon204 kwon204 added this to the 🫥 6.5차 스프린트 milestone Mar 17, 2025
@kwon204 kwon204 self-assigned this Mar 17, 2025
@kwon204 kwon204 requested review from dioo1461 and hamo-o as code owners March 17, 2025 00:35
@coderabbitai
Copy link

coderabbitai bot commented Mar 17, 2025

Walkthrough

This pull request enhances deployment workflows for both frontend and backend applications. In the GitHub Actions workflows, new steps have been added to securely copy deployment scripts and Nginx configuration files to an EC2 instance. The working directories and trigger paths have been updated accordingly. Additionally, two new shell scripts have been introduced to automate the deployment processes for backend and frontend applications, including service management and rollback capabilities. A minor update in the pre-push hook changes the shell interpreter from sh to bash.

Changes

File(s) Change Summary
.github/workflows/fe-cd.yml<br>.github/workflows/be-cd.yml Enhanced CD workflows: Added steps to copy deployment scripts (frontend_deploy.sh, backend_deploy.sh) and Nginx configs to EC2; updated working directories and monitored trigger paths.
.github/hooks/pre-push Updated shebang line from #!/bin/sh to #!/usr/bin/env bash to explicitly use Bash.
script/deploy/backend_deploy.sh<br>script/deploy/frontend_deploy.sh New deployment scripts: Introduced scripts for backend and frontend deployments that create directories, manage service execution (including health checks and rollback), copy build files, and clean up.
script/deploy/nginx/backend.conf<br>script/deploy/nginx/frontend.conf New Nginx configuration files: Added backend API proxy configurations with CORS and WebSocket support, and a frontend config for HTTP-to-HTTPS redirection along with security and caching settings.

Sequence Diagram(s)

sequenceDiagram
    participant GA as GitHub Actions (Frontend)
    participant EC2 as EC2 Instance
    participant FD as frontend_deploy.sh
    participant Nginx as Nginx Server

    GA->>EC2: Copy deploy script & Nginx config files
    EC2->>FD: Execute frontend_deploy.sh
    FD->>EC2: Clear old build & copy new build files
    FD->>Nginx: Copy configuration and run config test
    Nginx-->>FD: Return test result (pass/fail)
    FD->>EC2: Reload config or perform rollback
Loading
sequenceDiagram
    participant GA as GitHub Actions (Backend)
    participant EC2 as EC2 Instance
    participant BD as backend_deploy.sh
    participant SD as Systemd

    GA->>EC2: Copy backend_deploy.sh script
    EC2->>BD: Execute backend_deploy.sh
    BD->>EC2: Set up directories, copy backend JAR, and update symlink
    BD->>SD: Create/modify systemd service and reload daemon
    BD->>BD: Perform health checks (retry loop)
    BD-->>EC2: Complete deployment or trigger rollback
Loading

Possibly related PRs

Suggested reviewers

  • efdao
  • hamo-o

Poem

I'm a rabbit hopping through lines of code,
New workflows spring with each deploy mode.
Scripts now dance on EC2 so fine,
With Nginx leading the secure design.
Deployment leaps forward in a joyful spree—
Hop along, celebrate this automation spree!
🐰🌟

Tip

⚡🧪 Multi-step agentic review comment chat (experimental)
  • We're introducing multi-step agentic chat in review comments. This experimental feature enhances review discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments.
    - To enable this feature, set early_access to true under in the settings.
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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: 0

🧹 Nitpick comments (2)
.github/workflows/fe-cd.yml (1)

49-56: Use a pinned version for appleboy/scp-action.

Relying on @master can lead to unexpected changes downstream. Pinning the version (e.g., @v0.1.7) ensures consistent and reproducible deployments.

You can unify the version with the existing usage for consistency, for example:

-        uses: appleboy/scp-action@master
+        uses: appleboy/scp-action@v0.1.7
frontend/nginx/frontend.conf (1)

2-14: Prefer separate server blocks over if directives for domain redirects.

Using multiple if ($host = ...) blocks can introduce complexity or unexpected behavior in Nginx. Instead, consider defining distinct server blocks to handle each domain or using server_name directives for cleaner, more maintainable redirection logic.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 741618c and 4973e41.

📒 Files selected for processing (2)
  • .github/workflows/fe-cd.yml (1 hunks)
  • frontend/nginx/frontend.conf (1 hunks)
🔇 Additional comments (1)
frontend/nginx/frontend.conf (1)

25-25: Include api.unjemanna.site in the 443 server block if SSL should cover that domain.

Currently, only unjemanna.site and www.unjemanna.site appear under server_name for port 443. If the api.unjemanna.site domain requires HTTPS, consider including it here, unless it’s fully handled in /etc/nginx/conf.d/api.conf.

Copy link
Contributor

@hamo-o hamo-o left a comment

Choose a reason for hiding this comment

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

회의 내용과 같이 노션에 있는 다른 파일들도 추가 부탁드립니다!!

kwon204 added 4 commits March 19, 2025 01:49
- backend_deploy.sh, frontend_deploy.sh
- nginx/backend.conf frontend.conf
- fe-cd.yml, be-cd.yml 수정 (설정 파일을 ec2 서버로 전송하는 코드 추가)
sh로 실행하면 스크립트에 지원하지 않는 커맨드들이 있어서 에러 발생함.
그래서 bash로 수정
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: 3

🧹 Nitpick comments (11)
script/deploy/frontend_deploy.sh (1)

47-48: Add directory existence check before cleanup

The script attempts to clean up old backups without verifying the directory exists, which could cause errors if the directory is missing.

 # 오래된 백업 정리 (최근 5개만 유지)
 echo "오래된 프론트엔드 백업 정리 중..."
-cd $APP_DIR/frontend/backups && ls -t | tail -n +6 | xargs rm -f || true
+if [ -d "$APP_DIR/frontend/backups" ]; then
+  cd $APP_DIR/frontend/backups && ls -t | tail -n +6 | xargs rm -f || true
+else
+  echo "백업 디렉토리가 존재하지 않습니다."
+fi
script/deploy/nginx/frontend.conf (1)

1-21: Simplify HTTP to HTTPS redirection

The current configuration uses multiple if statements for redirection when a single return directive would be more efficient. Nginx recommends avoiding if statements when possible for performance reasons.

 server {
-        if ($host = www.unjemanna.site) {
-            return 301 https://$host$request_uri;
-        }
-
-
-        if ($host = api.unjemanna.site) {
-            return 301 https://$host$request_uri;
-        }
-
-
-        if ($host = unjemanna.site) {
-            return 301 https://$host$request_uri;
-        }
-
-
         listen 80;
         server_name unjemanna.site www.unjemanna.site api.unjemanna.site;

         return 301 https://$host$request_uri;
 }
script/deploy/nginx/backend.conf (1)

10-12: Consider adding www subdomain to CORS allowed origins

The CORS configuration only allows https://unjemanna.site but not https://www.unjemanna.site, which might cause CORS issues when users access the site via the www subdomain.

-        add_header 'Access-Control-Allow-Origin' 'https://unjemanna.site' always;
+        add_header 'Access-Control-Allow-Origin' '$http_origin' always;
+        add_header 'Access-Control-Allow-Credentials' 'true' always;
         add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PATCH, PUT' always;
         add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;
+
+        # Only allow specific origins
+        if ($http_origin !~ '^https://(www\.)?unjemanna\.site$') {
+            add_header 'Access-Control-Allow-Origin' '' always;
+        }

Similarly, update the same pattern in the OPTIONS block.

.github/workflows/be-cd.yml (2)

70-71: Verify that backend_deploy.sh exists and has execute permissions

The workflow now executes the backend deployment script from a new location, but there's no step ensuring the script has execute permissions.

          script: |
            cd ~/app/deploy
+           chmod +x ./backend_deploy.sh
            bash ./backend_deploy.sh

9-10: Add Nginx configuration files to workflow trigger paths

The workflow triggers when changes are made to backend/** or script/deploy/backend_deploy.sh, but should also trigger when the Nginx configuration files are changed since they're relevant for the backend deployment.

    paths:
      - "backend/**"
      - "script/deploy/backend_deploy.sh"
+     - "script/deploy/nginx/backend.conf"
script/deploy/backend_deploy.sh (6)

4-9: Variable Initialization and Directory Configuration

The variables (e.g., APP_DIR, BACKEND_DIR, BACKEND_JAR, LOG_DIR) are set up clearly. However, consider quoting the variable references (for example, "${APP_DIR}" and "${BACKEND_JAR}") to guard against issues with spaces or special characters in paths.


15-18: Log Directory Creation

Creating and setting permissions for the log directory using sudo is appropriate. It might be beneficial to check the command results or capture errors to handle any permission issues that could arise in different deployment environments.


25-29: Deploying the Backend JAR

Copying the latest JAR to the new release directory and updating the symlink is a correct approach.
Suggestion: Wrap variable references in quotes to avoid potential issues when file paths contain spaces. For example:

-cp $BACKEND_JAR $BACKEND_RELEASE_DIR/application.jar
+cp "$BACKEND_JAR" "$BACKEND_RELEASE_DIR/application.jar"
-ln -sfn $BACKEND_RELEASE_DIR $BACKEND_CURRENT_LINK
+ln -sfn "$BACKEND_RELEASE_DIR" "$BACKEND_CURRENT_LINK"

48-52: Service Deployment and Restart

Moving the generated service file to /etc/systemd/system/, reloading, and then restarting the service is demonstrated correctly.
Suggestion: Consider adding error checking around these commands to verify that the service file is correctly deployed and that the daemon reload is successful.


53-65: Backend Health Check Loop

The loop repeatedly checks the backend's health using curl and grep until it confirms the service is up or reaches the maximum retry limit.
Suggestion: To prevent a hanging curl call, include a timeout parameter (e.g., --max-time 2) in the curl command:

-if curl -s http://localhost:8080/health | grep -q "UP"; then
+if curl -s --max-time 2 http://localhost:8080/health | grep -q "UP"; then

78-83: Cleanup of Old Releases

The command for cleaning up old releases (keeping only the five most recent) is efficient.
Suggestion: As with previous file operations, quoting the directory variable can prevent issues with directory names containing spaces:

-cd $BACKEND_DIR/releases && ls -t | tail -n +6 | xargs rm -rf || true
+cd "$BACKEND_DIR/releases" && ls -t | tail -n +6 | xargs rm -rf || true
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4973e41 and 5f018f6.

📒 Files selected for processing (7)
  • .github/hooks/pre-push (1 hunks)
  • .github/workflows/be-cd.yml (3 hunks)
  • .github/workflows/fe-cd.yml (3 hunks)
  • script/deploy/backend_deploy.sh (1 hunks)
  • script/deploy/frontend_deploy.sh (1 hunks)
  • script/deploy/nginx/backend.conf (1 hunks)
  • script/deploy/nginx/frontend.conf (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .github/hooks/pre-push
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/fe-cd.yml
🔇 Additional comments (8)
script/deploy/nginx/frontend.conf (1)

56-57:

Details

❓ Verification inconclusive

Missing cert.conf reference

The configuration includes a reference to /etc/nginx/conf.d/cert.conf, but there's no mention of this file being created or copied in the deployment script.

Please verify that cert.conf exists or is created during the deployment process. You should add a step in the deployment script to handle the SSL certificate configuration:


🏁 Script executed:

#!/bin/bash
# Check if cert.conf exists on the target server
ssh $EC2_USERNAME@$EC2_HOST "ls -la /etc/nginx/conf.d/cert.conf"

Length of output: 138


Manual SSL Certificate Configuration Verification Needed

We've attempted to verify the presence of /etc/nginx/conf.d/cert.conf using the provided script, but the check failed with an error indicating that the ssh command is not available. This leaves us with inconclusive evidence on whether the file is created or deployed. Please manually verify in an environment where ssh is available that cert.conf exists (or is generated/copied) during the deployment process. Also, ensure that the deployment script includes the necessary step to handle the SSL certificate configuration if the file is missing.

.github/workflows/be-cd.yml (1)

43-51: LGTM: Good addition of deploy script copying

The addition of a step to copy the deployment script to the EC2 instance is a good practice. This ensures that the latest version of the deployment script is used.

script/deploy/backend_deploy.sh (6)

1-3: File Header and Safety Configuration

The shebang and set -e directive ensure that the script exits immediately on any error. This is a good safeguard for deployment procedures.


10-14: Timestamp and Release Directory Setup

Generating a timestamp with the date command and using it to create a release directory is well implemented. This provides a clear mechanism for versioning and rollback. No changes are needed.


19-21: Backend Release Directory Structure

Using mkdir -p to create the release directory is a straightforward, effective approach. This segment is correctly implemented.


22-24: Recording Previous Deployment State

Capturing the previous release path via readlink (with a fallback to an empty string) is a good strategy for implementing rollback procedures. No changes are needed here.


30-47: Service File Generation

The heredoc used for generating the systemd unit file is clear and effective. Variable substitution works as intended to insert paths into the service file. This segment is good to go.


66-77: Rollback Mechanism

The rollback strategy checks for an available previous deployment and reverts the symlink if the backend fails to become healthy. This is a robust approach to ensure service availability.

Comment on lines +40 to +43
sudo rm -rf $FRONTEND_DIR/*
sudo tar -xzf $APP_DIR/frontend/backups/frontend_$TIMESTAMP.tar.gz -C $FRONTEND_DIR
echo "이전 버전으로 롤백했습니다."
exit 1
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Rollback functionality references an undefined variable

The rollback code uses $TIMESTAMP which is undefined in this script. The rollback will fail when needed because of this missing variable.

+# 배포 전 현재 프론트엔드의 백업 생성
+TIMESTAMP=$(date +%Y%m%d%H%M%S)
+mkdir -p $APP_DIR/frontend/backups
+sudo tar -czf $APP_DIR/frontend/backups/frontend_$TIMESTAMP.tar.gz -C $FRONTEND_DIR .
+echo "현재 프론트엔드 버전이 백업되었습니다."
+
 # 새 버전 배포
 sudo rm -rf $FRONTEND_DIR/*
 sudo cp -r $APP_DIR/frontend/dist/* $FRONTEND_DIR/

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +23 to +26
server {
listen 443 ssl;
server_name unjemanna.site www.unjemanna.site;

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Server block is missing api.unjemanna.site

The server block for HTTPS doesn't include api.unjemanna.site in the server_name directive, while it's included in the HTTP block. This inconsistency might cause issues when accessing the API via HTTPS.

 server {
         listen 443 ssl;
-        server_name unjemanna.site www.unjemanna.site;
+        server_name unjemanna.site www.unjemanna.site api.unjemanna.site;
📝 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.

Suggested change
server {
listen 443 ssl;
server_name unjemanna.site www.unjemanna.site;
server {
listen 443 ssl;
server_name unjemanna.site www.unjemanna.site api.unjemanna.site;

Comment on lines +10 to +20
add_header 'Access-Control-Allow-Origin' 'https://unjemanna.site' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PATCH, PUT' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;

if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://unjemanna.site';
add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PUT, OPTIONS, PATCH';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Access-Control-Max-Age' 86400;
return 204;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

CORS headers inconsistency between normal responses and OPTIONS

The CORS headers are defined twice with slight differences between normal responses and OPTIONS requests. The Access-Control-Allow-Methods values are different, which could cause inconsistent behavior.

-        add_header 'Access-Control-Allow-Origin' 'https://unjemanna.site' always;
-        add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PATCH, PUT' always;
-        add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;
+        add_header 'Access-Control-Allow-Origin' 'https://unjemanna.site' always;
+        add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PUT, OPTIONS, PATCH' always;
+        add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;

         if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' 'https://unjemanna.site';
                add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PUT, OPTIONS, PATCH';
                add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
                add_header 'Access-Control-Max-Age' 86400;
                return 204;
         }
📝 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.

Suggested change
add_header 'Access-Control-Allow-Origin' 'https://unjemanna.site' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PATCH, PUT' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://unjemanna.site';
add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PUT, OPTIONS, PATCH';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Access-Control-Max-Age' 86400;
return 204;
}
add_header 'Access-Control-Allow-Origin' 'https://unjemanna.site' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PUT, OPTIONS, PATCH' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://unjemanna.site';
add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PUT, OPTIONS, PATCH';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Access-Control-Max-Age' 86400;
return 204;
}

Copy link
Contributor

@hamo-o hamo-o left a comment

Choose a reason for hiding this comment

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

image
처음에 서버에 패키지 까는 요부분은 없는데 이것도 올려주실 수 있나요?
pm2 설치해야 해서요

@kwon204
Copy link
Contributor Author

kwon204 commented Mar 21, 2025

image 처음에 서버에 패키지 까는 요부분은 없는데 이것도 올려주실 수 있나요? pm2 설치해야 해서요

그거는 스크립트가 아니라 제가 하나씩 타이핑해서 설치할 거 모아둔 거에요.
서버에 pm2 설치하긴 했는데 올릴까요? 아니면 실행 파일로 바꿔서 올릴까요?

Copy link
Contributor

@hamo-o hamo-o left a comment

Choose a reason for hiding this comment

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

아 그러면 일단 넘어가도 될 것 같습니다 수고하셨어요

@kwon204 kwon204 merged commit 1736e4d into dev Mar 22, 2025
1 check passed
@kwon204 kwon204 deleted the feature/be/moving branch March 22, 2025 05:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants