Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

be/feat: github actions 배포 설정 #220

Merged
merged 2 commits into from
Mar 1, 2025
Merged

be/feat: github actions 배포 설정 #220

merged 2 commits into from
Mar 1, 2025

Conversation

dlwldnjs1009
Copy link
Contributor

@dlwldnjs1009 dlwldnjs1009 commented Dec 25, 2024

변경 사항

github actions .yml 파일 설정했습니

테스트 결과 (테스트를 했으면)

테스트는 push가 되어봐야 테스트를 할 수 있어서 테스트를 아직 못해봤습니다.

+α Checklist

  • 자바 코드 컨벤션을 지키면서 프로그래밍했는가?
  • 한 메서드에 오직 한 단계의 들여쓰기(indent)만 허용했는가?
  • else 예약어를 쓰지 않았는가?
  • 모든 원시값과 문자열을 포장했는가?
  • 콜렉션에 대해 일급 콜렉션을 적용했는가?
  • 3개 이상의 인스턴스 변수를 가진 클래스를 구현하지 않았는가? (가능하면 인스턴스 변수의 수를 줄이기 위해 노력한다.)
  • getter/setter 없이 구현했는가? (단, DTO는 허용한다.)
  • 메소드의 인자 수를 제한했는가? (4개 이상의 인자는 허용하지 않는다. 3개도 가능하면 줄이기 위해 노력해 본다.)
  • 코드 한 줄에 점(.)을 하나만 허용했는가?
  • 메소드가 한가지 일만 담당하도록 구현했는가?
  • 클래스를 작게 유지하기 위해 노력했는가?

Summary by CodeRabbit

  • New Features

    • Introduced an automated deployment pipeline that streamlines backend updates and production releases.
    • Added a dedicated process for building production-ready containers.
  • Chores

    • Streamlined the build process by disabling legacy tasks.
  • Refactor

    • Expanded the range of trusted domains for cross-origin requests to improve integration support.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Code review by ChatGPT

Copy link

coderabbitai bot commented Mar 1, 2025

Walkthrough

This change introduces continuous deployment automation for the backend application. A new GitHub Actions workflow (backend-cd.yml) automates the build, Docker image creation, and deployment process upon pushes to branches matching the pattern be/** and pull requests to main and develop. Additionally, a production Dockerfile is added, the Gradle build configuration is updated to disable the jar task, and the CORS configuration has been expanded to permit additional allowed origins.

Changes

File(s) Change Summary
.github/workflows/backend-cd.yml New GitHub Actions workflow automating backend deployment on pushes to branches matching be/** and pull requests to main and develop. It checks out code, sets up Java, builds with Gradle, logs into Docker Hub, builds and pushes a Docker image, and deploys to AWS EC2 via SSH.
backend/Dockerfile.prod New Dockerfile for production using OpenJDK 17. It accepts a JAR_FILE argument, copies the JAR file (renamed to techeer-resume-0.0.1-SNAPSHOT.jar), and sets the Java command as the container’s entry point.
backend/build.gradle Added a configuration block to disable the jar task (jar { enabled = false }), preventing the creation of a jar file during the build process.
backend/src/main/java/com/techeer/backend/global/config/SecurityConfig.java Modified the CORS configuration to expand the allowed origins from three to nine, including additional domains and IP addresses.

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer
    participant GH as GitHub Actions
    participant Gradle as Build Process
    participant Docker as Docker Hub
    participant AWS as AWS EC2

    Dev->>GH: Push to 'be/**' branch or PR to 'main/develop'
    GH->>GH: Checkout repository code
    GH->>GH: Set up Java (JDK 17) & grant permissions
    GH->>Gradle: Execute Gradle build
    Gradle-->>GH: Build completed
    GH->>Docker: Log in and build Docker image
    Docker-->>GH: Image build confirmation
    GH->>Docker: Push Docker image to Docker Hub
    GH->>AWS: SSH into EC2 and deploy via docker-compose
    AWS-->>GH: Deployment complete
Loading

Poem

I’m a rabbit with a code-filled heart,
Hopping through workflows, a fresh new start,
With Docker images and Java so keen,
Gradle builds while I bask in green,
Leaping over bugs with a joyful cheer,
Celebrating code magic far and near!


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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.

lsh1215
lsh1215 previously approved these changes Mar 1, 2025
Copy link
Member

@lsh1215 lsh1215 left a comment

Choose a reason for hiding this comment

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

확인 완료했습니다. 추가적으로 머지되면 확인해서 알려주세요

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

🧹 Nitpick comments (3)
backend/Dockerfile.prod (1)

2-2: Use specific JAR file instead of wildcard pattern

Using a wildcard pattern for the JAR file could lead to unexpected behavior if multiple JAR files exist in the build directory.

FROM openjdk:17-jdk
-ARG JAR_FILE=build/libs/*.jar
+ARG JAR_FILE=build/libs/techeer-resume-0.0.1-SNAPSHOT.jar
COPY ${JAR_FILE} techeer-resume-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java","-jar","/techeer-resume-0.0.1-SNAPSHOT.jar"]
.github/workflows/backend-cd.yml (2)

28-30: Tag Docker images with version for better traceability

Using only "latest" tag for Docker images makes it difficult to track which version is deployed and rollback if needed.

- run: docker buildx build --platform linux/amd64 -f Dockerfile.prod -t ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest .
- name: 도커허브에 이미지 푸시
- run: docker push ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest
+ run: |
+   SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7)
+   docker buildx build --platform linux/amd64 -f backend/Dockerfile.prod -t ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest -t ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:$SHORT_SHA backend/
+ name: 도커허브에 이미지 푸시
+ run: |
+   SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7)
+   docker push ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest
+   docker push ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:$SHORT_SHA

40-40: Add newline at end of file

The file is missing a newline at the end, which is a YAML best practice.

docker-compose --env-file .env.production up -d
+
🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 40-40: no new line character at the end of file

(new-line-at-end-of-file)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 6e129eb and 70ba9d9.

📒 Files selected for processing (4)
  • .github/workflows/backend-cd.yml (1 hunks)
  • backend/Dockerfile.prod (1 hunks)
  • backend/build.gradle (1 hunks)
  • backend/src/main/java/com/techeer/backend/global/config/SecurityConfig.java (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • backend/build.gradle
🧰 Additional context used
🪛 actionlint (1.7.4)
.github/workflows/backend-cd.yml

12-12: 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)


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

(action)


23-23: the runner of "docker/login-action@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🪛 YAMLlint (1.35.1)
.github/workflows/backend-cd.yml

[error] 40-40: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (1)
.github/workflows/backend-cd.yml (1)

12-14: 🛠️ Refactor suggestion

✅ Verification successful

Update GitHub Actions to latest versions

The workflow uses outdated versions of GitHub Actions which may have security vulnerabilities or missing features.

- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
- uses: docker/login-action@v1
+ uses: docker/login-action@v3

Also applies to: 23-23, 32-32


🌐 Web query:

What are the latest versions of GitHub Actions checkout, setup-java, and docker/login-action?

💡 Result:

GitHub Actions are continually updated, but based on current documentation and release notes, here are the latest versions of key actions as of March 2025:

GitHub Actions Versions

  1. actions/checkout
    Latest version: v4
    Used to clone repositories into runners' workspaces for CI/CD pipelines[1][9]. Recent updates focus on improved caching and security enhancements[9].

  2. actions/setup-java
    Latest version: v4
    Supports multiple Java distributions (Temurin, Zulu, etc.) with advanced features like dependency caching and GPG key configuration[2][6]. The v4 release introduced:

    • Expanded distribution support
    • Improved version resolution logic[2][10]
  3. docker/login-action
    Latest version: v3.3.0
    Provides secure authentication for container registries with:

    • Enhanced error handling
    • Updated proxy agent dependencies[8]
      Supports Docker Hub, GHCR, and cloud registries through workload identity federation[3][7].
Action Latest Version Key Improvements
actions/checkout v4 Security patches, caching optimizations
actions/setup-java v4 Multi-distribution support, Maven tools
docker/login v3.3.0 Proxy support, AWS auth enhancements

For production workflows, always verify version compatibility and review release notes before upgrading[1][8][10].

Citations:


Upgrade GitHub Actions to Latest Stable Versions

Please update the GitHub Actions in your backend-cd.yml workflow to ensure you benefit from the latest security and feature improvements. Based on current documentation, make the following changes:

  • Checkout Action:

    - uses: actions/checkout@v3
    + uses: actions/checkout@v4
  • Setup Java Action:

    - uses: actions/setup-java@v3
    + uses: actions/setup-java@v4
  • Docker Login Action:

    - uses: docker/login-action@v1
    + uses: docker/[email protected]

These updates should also be applied to similar occurrences in lines 23 and 32. This will help mitigate potential vulnerabilities and leverage newer functionalities available in these actions.

🧰 Tools
🪛 actionlint (1.7.4)

12-12: 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)


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

(action)

Comment on lines +3 to +4
COPY ${JAR_FILE} techeer-resume-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java","-jar","/techeer-resume-0.0.1-SNAPSHOT.jar"]
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix path inconsistency and improve container security

There's a path inconsistency between the COPY and ENTRYPOINT commands. Additionally, the Dockerfile could be improved with several production best practices.

FROM openjdk:17-jdk
ARG JAR_FILE=build/libs/*.jar
-COPY ${JAR_FILE} techeer-resume-0.0.1-SNAPSHOT.jar
-ENTRYPOINT ["java","-jar","/techeer-resume-0.0.1-SNAPSHOT.jar"]
+WORKDIR /app
+COPY ${JAR_FILE} app.jar
+RUN addgroup --system --gid 1001 appuser \
+    && adduser --system --uid 1001 --ingroup appuser appuser \
+    && chown -R appuser:appuser /app
+USER appuser
+HEALTHCHECK --interval=30s --timeout=3s --retries=3 CMD wget -qO- http://localhost:8080/actuator/health || exit 1
+ENTRYPOINT ["java", "-XX:+UseContainerSupport", "-XX:MaxRAMPercentage=75.0", "-jar", "app.jar"]
📝 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
COPY ${JAR_FILE} techeer-resume-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java","-jar","/techeer-resume-0.0.1-SNAPSHOT.jar"]
FROM openjdk:17-jdk
ARG JAR_FILE=build/libs/*.jar
WORKDIR /app
COPY ${JAR_FILE} app.jar
RUN addgroup --system --gid 1001 appuser \
&& adduser --system --uid 1001 --ingroup appuser appuser \
&& chown -R appuser:appuser /app
USER appuser
HEALTHCHECK --interval=30s --timeout=3s --retries=3 CMD wget -qO- http://localhost:8080/actuator/health || exit 1
ENTRYPOINT ["java", "-XX:+UseContainerSupport", "-XX:MaxRAMPercentage=75.0", "-jar", "app.jar"]

@@ -40,7 +40,7 @@ public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();

config.setAllowCredentials(true);
config.setAllowedOrigins(List.of("http://localhost:8080", "http://localhost:5173", "http://backend:8080"));
config.setAllowedOrigins(List.of("http://localhost:8080", "http://localhost:5173", "http://backend:8080", "http://backend:5173", "http://rexume.site:8080", "http://rexume.site:5173", "http://rexume.site", "http://52.78.85.237:8080", "http://52.78.85.237:5173"));
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use HTTPS for production domains and externalize CORS configuration

The CORS configuration has security and maintainability issues:

  1. Production domains should use HTTPS instead of HTTP for secure communication
  2. Hard-coded IP addresses (52.78.85.237) make configuration changes difficult
  3. The long list of origins would be better managed through configuration properties

Consider refactoring to use environment-specific properties:

-config.setAllowedOrigins(List.of("http://localhost:8080", "http://localhost:5173", "http://backend:8080", "http://backend:5173", "http://rexume.site:8080", "http://rexume.site:5173", "http://rexume.site", "http://52.78.85.237:8080", "http://52.78.85.237:5173"));
+// Load from application properties
+String[] allowedOrigins = environment.getProperty("cors.allowed-origins", String[].class);
+config.setAllowedOrigins(Arrays.asList(allowedOrigins));

Then define in your application-{profile}.properties/yml:

# Local development
cors.allowed-origins=http://localhost:8080,http://localhost:5173,http://backend:8080,http://backend:5173

# Production
# cors.allowed-origins=https://rexume.site,https://www.rexume.site,https://api.rexume.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
config.setAllowedOrigins(List.of("http://localhost:8080", "http://localhost:5173", "http://backend:8080", "http://backend:5173", "http://rexume.site:8080", "http://rexume.site:5173", "http://rexume.site", "http://52.78.85.237:8080", "http://52.78.85.237:5173"));
// Load from application properties
String[] allowedOrigins = environment.getProperty("cors.allowed-origins", String[].class);
config.setAllowedOrigins(Arrays.asList(allowedOrigins));

Comment on lines 38 to 40
script: |
docker pull ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest
docker-compose --env-file .env.production up -d
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add health check verification and rollback strategy

The workflow doesn't verify if the deployment was successful and doesn't have a rollback strategy in case of failure.

  script: |
    docker pull ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest
-   docker-compose --env-file .env.production up -d
+   # Check if .env.production exists
+   if [ ! -f .env.production ]; then
+     echo ".env.production file not found! Deployment failed."
+     exit 1
+   fi
+   
+   # Store current container ID for potential rollback
+   CURRENT_CONTAINER=$(docker ps -q --filter "name=${CONTAINER_NAME}")
+   
+   # Deploy new version
+   docker-compose --env-file .env.production up -d
+   
+   # Wait for service to become healthy
+   echo "Waiting for service to become healthy..."
+   sleep 30
+   
+   # Check if new deployment is running properly
+   if ! curl -f --retry 5 --retry-delay 5 http://localhost:8080/actuator/health; then
+     echo "Health check failed! Rolling back to previous version..."
+     if [ -n "$CURRENT_CONTAINER" ]; then
+       # Rollback to previous container
+       docker start $CURRENT_CONTAINER
+       docker-compose down
+     else
+       # No previous container to rollback to
+       echo "No previous container found for rollback."
+     fi
+     exit 1
+   fi
+   
+   echo "Deployment successful!"
📝 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
script: |
docker pull ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest
docker-compose --env-file .env.production up -d
script: |
docker pull ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest
# Check if .env.production exists
if [ ! -f .env.production ]; then
echo ".env.production file not found! Deployment failed."
exit 1
fi
# Store current container ID for potential rollback
CURRENT_CONTAINER=$(docker ps -q --filter "name=${CONTAINER_NAME}")
# Deploy new version
docker-compose --env-file .env.production up -d
# Wait for service to become healthy
echo "Waiting for service to become healthy..."
sleep 30
# Check if new deployment is running properly
if ! curl -f --retry 5 --retry-delay 5 http://localhost:8080/actuator/health; then
echo "Health check failed! Rolling back to previous version..."
if [ -n "$CURRENT_CONTAINER" ]; then
# Rollback to previous container
docker start $CURRENT_CONTAINER
docker-compose down
else
# No previous container found for rollback.
echo "No previous container found for rollback."
fi
exit 1
fi
echo "Deployment successful!"
🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 40-40: no new line character at the end of file

(new-line-at-end-of-file)

username: ${{ secrets.DOCKER_USER_NAME }}
password: ${{ secrets.DOCKER_USER_PW }}
- name: 이미지 빌드
run: docker buildx build --platform linux/amd64 -f Dockerfile.prod -t ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest .
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix Dockerfile path and add caching for faster builds

The Dockerfile path is incorrect and should include the backend directory. Additionally, adding caching can significantly improve build times.

- run: docker buildx build --platform linux/amd64 -f Dockerfile.prod -t ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest .
+ name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+ name: Cache Docker layers
+ uses: actions/cache@v3
+ with:
+   path: /tmp/.buildx-cache
+   key: ${{ runner.os }}-buildx-${{ github.sha }}
+   restore-keys: |
+     ${{ runner.os }}-buildx-
+ name: 이미지 빌드
+ run: docker buildx build --platform linux/amd64 -f backend/Dockerfile.prod -t ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest --cache-from=type=local,src=/tmp/.buildx-cache --cache-to=type=local,dest=/tmp/.buildx-cache-new,mode=max backend/
📝 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
run: docker buildx build --platform linux/amd64 -f Dockerfile.prod -t ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest .
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Cache Docker layers
uses: actions/cache@v3
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: 이미지 빌드
run: docker buildx build --platform linux/amd64 -f backend/Dockerfile.prod -t ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest --cache-from=type=local,src=/tmp/.buildx-cache --cache-to=type=local,dest=/tmp/.buildx-cache-new,mode=max backend/

Comment on lines +19 to +29
run: chmod +x gradlew
- name: Gradle로 빌드(CI)
run: ./gradlew build
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Set working directory for Gradle commands

The Gradle commands are being executed at the repository root, but the Gradle wrapper might be in the backend directory.

If gradlew is indeed in the backend directory, use this fix:

- name: Gradle Wrapper 실행 권한 추가
- run: chmod +x gradlew
- name: Gradle로 빌드(CI)
- run: ./gradlew build
+ name: Gradle Wrapper 실행 권한 추가
+ run: chmod +x backend/gradlew
+ name: Gradle로 빌드(CI)
+ working-directory: ./backend
+ run: ./gradlew build

🏁 Script executed:

#!/bin/bash
# Check if gradlew exists in repo root or in backend directory
if [ -f "gradlew" ]; then
  echo "Gradle wrapper found in root directory"
else
  echo "Gradle wrapper not found in root directory"
  if [ -f "backend/gradlew" ]; then
    echo "Gradle wrapper found in backend directory"
  else
    echo "Gradle wrapper not found in backend directory either"
  fi
fi

Length of output: 237


Gradle Wrapper Location Adjustment Required

The verification confirms that the Gradle wrapper is located in the backend directory. Please update the workflow file to use the Gradle wrapper from ./backend by modifying the commands as follows:

  • Change the execute permission command to target backend/gradlew.
  • Set the working-directory to ./backend for the build command.
- name: Gradle Wrapper 실행 권한 추가
- run: chmod +x gradlew
- name: Gradle로 빌드(CI)
- run: ./gradlew build
+ name: Gradle Wrapper 실행 권한 추가
+ run: chmod +x backend/gradlew
+ name: Gradle로 빌드(CI)
+ working-directory: ./backend
+ run: ./gradlew build
📝 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
run: chmod +x gradlew
- name: Gradle로 빌드(CI)
run: ./gradlew build
- name: Gradle Wrapper 실행 권한 추가
run: chmod +x backend/gradlew
- name: Gradle로 빌드(CI)
working-directory: ./backend
run: ./gradlew build

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

🧹 Nitpick comments (5)
.github/workflows/backend-cd.yml (5)

19-20: Upgrade Checkout Action Version
The checkout step uses actions/checkout@v3, but static analysis suggests that this version is outdated. Consider upgrading to a more recent and supported version (e.g., actions/checkout@v4) to benefit from performance and security improvements.

Suggested Diff:

-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
🧰 Tools
🪛 actionlint (1.7.4)

20-20: 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)


21-25: Upgrade Setup-Java Action Version
The workflow uses actions/setup-java@v3 for JDK setup. Similar to the checkout action, it is recommended to update this action to a newer version (if available) to ensure compatibility and security.

Suggested Diff:

-        uses: actions/setup-java@v3
+        uses: actions/setup-java@v4
🧰 Tools
🪛 actionlint (1.7.4)

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

(action)


30-34: Update Docker Login Action Version
The Docker login step currently uses docker/login-action@v1. Updating it to a more recent version (such as v2) can improve security and performance.

Suggested Diff:

-        uses: docker/login-action@v1
+        uses: docker/login-action@v2
🧰 Tools
🪛 actionlint (1.7.4)

31-31: the runner of "docker/login-action@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


35-36: Verify Docker Build Command Context and Consider Caching
The image build step specifies -f Dockerfile.prod, and with the working directory set to backend, it should correctly reference the Dockerfile located there. Additionally, consider augmenting the build command with caching options (as suggested in previous reviews) to speed up subsequent builds.

Possible Enhancement Diff:

-        run: docker buildx build --platform linux/amd64 -f Dockerfile.prod -t ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest .
+        run: docker buildx build --platform linux/amd64 -f Dockerfile.prod -t ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest --cache-from=type=local,src=/tmp/.buildx-cache --cache-to=type=local,dest=/tmp/.buildx-cache-new,mode=max .

51-51: Ensure Newline at End of File
YAMLlint indicates that the file is missing a newline at the end. Adding a newline will resolve this formatting issue.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 70ba9d9 and 7715a48.

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

20-20: 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)


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

(action)


31-31: the runner of "docker/login-action@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🔇 Additional comments (4)
.github/workflows/backend-cd.yml (4)

1-11: Event Triggers and Branch Filters are Correctly Defined
The workflow’s trigger events and branch filters (using push for branches matching 'be/**' and pull_request on main and develop) are set up as intended.


12-18: Job Defaults with Working-Directory Configured
Setting the default working directory to backend is appropriate given that subsequent commands (e.g., the Gradle wrapper execution and Docker build) depend on files in that directory. Ensure that this behavior is intentional for all run steps.


26-29: Gradle Wrapper Execution in the Correct Directory
Since the job’s default working directory is set to backend, running chmod +x gradlew and then executing ./gradlew build is appropriate—provided that the Gradle wrapper (gradlew) is indeed located in the backend directory. Verify that all relevant files are in place.


37-38: Docker Push Step Looks Good
The step that pushes the built Docker image to Docker Hub is straightforward and correctly uses the secret variables for authentication.

Comment on lines +39 to +50
- name: AWS EC2에 ssh 접속 후 배포
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.AWS_IP }}
port: 22
username: ubuntu
key: ${{ secrets.AWS_KEY }}
script: |
sudo docker rm -f $(docker ps -qa)
docker pull ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest
docker-compose --env-file .env.production up -d
docker image prune -f
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

AWS EC2 Deployment: Pin Action Version and Caution on Container Removal
Several points to consider for the SSH deployment step:

  • Action Version Pinning: Using appleboy/ssh-action@master is not ideal because relying on a branch head can introduce unexpected changes. It is recommended to pin to a specific stable version.
  • Destructive Container Removal: The command sudo docker rm -f $(docker ps -qa) forcefully stops and removes all containers on the host. Confirm that this behavior is acceptable, as it could impact other running services.
  • Enhancement Opportunity: Consider integrating health check verification and a rollback strategy in case the deployment fails.

Suggested Diff for Pinning Version:

-        uses: appleboy/ssh-action@master
+        uses: appleboy/[email protected]
📝 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
- name: AWS EC2에 ssh 접속 후 배포
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.AWS_IP }}
port: 22
username: ubuntu
key: ${{ secrets.AWS_KEY }}
script: |
sudo docker rm -f $(docker ps -qa)
docker pull ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest
docker-compose --env-file .env.production up -d
docker image prune -f
- name: AWS EC2에 ssh 접속 후 배포
uses: appleboy/ssh-action@v0.1.8
with:
host: ${{ secrets.AWS_IP }}
port: 22
username: ubuntu
key: ${{ secrets.AWS_KEY }}
script: |
sudo docker rm -f $(docker ps -qa)
docker pull ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest
docker-compose --env-file .env.production up -d
docker image prune -f

Copy link
Member

@lsh1215 lsh1215 left a comment

Choose a reason for hiding this comment

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

goooood!

dlwldnjs1009 and others added 2 commits March 1, 2025 22:31
이벤트 트리거:
on: 아래에 push 이벤트는 develop 브랜치에, 그리고 pull_request 이벤트는 main과 develop 브랜치에 대해 트리거되도록 수정

기본 작업 디렉토리:
jobs.deploy.defaults.run.working-directory를 backend로 지정해 모든 run 단계가 backend 디렉토리에서 실행되도록 수정
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: 4

♻️ Duplicate comments (1)
.github/workflows/backend-cd.yml (1)

39-40: 🛠️ Refactor suggestion

Pinning SSH Action Version

The workflow currently uses appleboy/ssh-action@master, which is not pinned to a specific version. For stability and security reasons, please pin the action to a specific release (e.g., appleboy/[email protected]).

🧹 Nitpick comments (3)
.github/workflows/backend-cd.yml (3)

12-17: Job Defaults and Working Directory

The job defaults specify a working-directory of backend, which simplifies the step commands. For clarity and consistency, consider explicitly using a relative path (e.g., ./backend) if that better reflects your repository structure.


35-36: Docker Build Command Enhancements

The build command references Dockerfile.prod. Since the default working directory is set to backend, this assumes that Dockerfile.prod is located there. If that is the case, the command is correct. However, consider integrating Buildx caching parameters to accelerate subsequent builds, as suggested in prior reviews.


51-51: File Ending: Missing New Line

A newline at the end of the file is recommended for POSIX compliance and to prevent potential issues with file parsing. Please ensure a newline character is added at the end.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7715a48 and 9ac68a3.

📒 Files selected for processing (4)
  • .github/workflows/backend-cd.yml (1 hunks)
  • backend/Dockerfile.prod (1 hunks)
  • backend/build.gradle (1 hunks)
  • backend/src/main/java/com/techeer/backend/global/config/SecurityConfig.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • backend/src/main/java/com/techeer/backend/global/config/SecurityConfig.java
  • backend/Dockerfile.prod
  • backend/build.gradle
🧰 Additional context used
🪛 actionlint (1.7.4)
.github/workflows/backend-cd.yml

20-20: 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)


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

(action)


31-31: the runner of "docker/login-action@v1" 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 (2)
  • GitHub Check: deploy
  • GitHub Check: deploy
🔇 Additional comments (5)
.github/workflows/backend-cd.yml (5)

1-2: Workflow Naming and Clarity

The workflow name "배포" is succinct and descriptive. Ensure that the use of a localized name aligns with your team's conventions.


3-11: Trigger Configuration

The workflow is set to trigger on pushes to branches matching 'be/**' and on pull requests targeting main and develop. This configuration appears appropriate for your deployment strategy. Verify that these patterns match your branch naming conventions.


26-29: Gradle Wrapper and Build Execution

By setting the default working-directory to backend, the steps for granting execute permissions and building with the Gradle wrapper (./gradlew) are correctly simplified. Ensure that the Gradle wrapper resides in the backend directory. The current implementation is clear; no further changes are needed.


37-38: Docker Push Step

The step for pushing the Docker image to Docker Hub appears correctly implemented. Ensure that your tagging and repository naming conventions meet your deployment and versioning strategies.


41-45: SSH Configuration for AWS EC2

The AWS EC2 SSH configuration (host, port, username, and key) is correctly set up using secure GitHub secrets. No issues are found in this segment.

Comment on lines +19 to +20
- name: 체크아웃
uses: actions/checkout@v3
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Action Version Update: Checkout

The checkout step uses actions/checkout@v3. Static analysis indicates that this version may be outdated. Consider updating to the latest stable release (e.g., actions/checkout@v4) to benefit from performance improvements and security fixes.

🧰 Tools
🪛 actionlint (1.7.4)

20-20: 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)

Comment on lines +21 to +25
- name: JDK 17 사용
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'corretto'
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Action Version Update: Setup Java

The workflow employs actions/setup-java@v3 to set up JDK 17 with the Corretto distribution. Upgrading to a newer version (if available) could yield additional fixes and improvements.

🧰 Tools
🪛 actionlint (1.7.4)

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

(action)

Comment on lines +30 to +34
- name: 도커허브에 로그인
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USER_NAME }}
password: ${{ secrets.DOCKER_USER_PW }}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Update Docker Login Action Version

The login step uses docker/login-action@v1, which static analysis flags as outdated. Upgrading to a newer version (e.g., docker/login-action@v2) will help improve security and compatibility.

🧰 Tools
🪛 actionlint (1.7.4)

31-31: the runner of "docker/login-action@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

Comment on lines +46 to +50
script: |
sudo docker rm -f $(docker ps -qa)
docker pull ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_IMAGE_NAME }}-be:latest
docker-compose --env-file .env.production up -d
docker image prune -f
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Deployment Script: Caution and Enhancements

The deployment script begins with a forceful removal of all Docker containers using sudo docker rm -f $(docker ps -qa). This command is highly destructive and might inadvertently stop unrelated services running on the host. Consider refining it to target only the specific container(s) associated with your application. Additionally, the script invokes docker-compose --env-file .env.production up -d without any subsequent health check or rollback mechanism. Implementing a health check (and optionally a rollback strategy) would enhance the reliability of your deployment process.

@dlwldnjs1009 dlwldnjs1009 merged commit 7f6b9ed into develop Mar 1, 2025
6 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Mar 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants