백엔드 릴리즈 워크플로우 분리 및 자동화#234
Conversation
Split backend automation into two paths. Main and pull request runs now create a local Docker bundle artifact. Tag-based runs handle AWS deployment and GitHub Release creation. Closes: #233
📊 코드 커버리지 리포트
|
There was a problem hiding this comment.
release.yml이 이미지를 :${{ github.ref_name }}과 :latest 두 태그로 푸시하는 점은 좋은 것 같습니다.
다만 실제 배포 경로를 보면, deploy.sh가 docker compose pull을 사용하고 docker/docker-compose.yml의 blue/green이 image: linkivingsofa/core:latest로 고정되어 있어서, 어떤 버전 태그로 릴리즈하든 운영에는 항상 latest가 배포됩니다.
이로 인해:
- 푸시하는 버전 태그(:v1.2.0 등)가 배포에 사용되지 않습니다.
- 특정 버전으로의 롤백이 불가능합니다.
버전 태그 릴리즈의 의미를 살리려면, 배포 시 이미지 태그를 주입하는 방식이 더 좋을 것 같습니다.
예를 들어 compose의 image를 linkivingsofa/core:${IMAGE_TAG:-latest}로 두고, release.yml에서 IMAGE_TAG=${{ github.ref_name }}를 deploy 단계에 전달하면, pull이 해당 버전을 받고 롤백도 태그 변경으로 가능해질 것 같습니다.
| run: | | ||
| mkdir -p ./src/main/resources | ||
| cat <<'EOF' > ./src/main/resources/application-local.yml | ||
| spring: | ||
| datasource: | ||
| driver-class-name: org.postgresql.Driver | ||
| url: ${DB_URL:jdbc:postgresql://localhost:5432/linkiving_local} | ||
| username: ${DB_USERNAME:linkiving} | ||
| password: ${DB_PASSWORD:linkiving} | ||
|
|
||
| data: | ||
| redis: | ||
| host: ${REDIS_HOST:localhost} | ||
| port: ${REDIS_PORT:6379} | ||
| ssl: | ||
| enabled: ${REDIS_SSL_ENABLED:false} | ||
| repositories: | ||
| enabled: false | ||
|
|
||
| jpa: | ||
| database: postgresql | ||
| hibernate: | ||
| ddl-auto: update | ||
| show-sql: true | ||
| open-in-view: false | ||
| properties: | ||
| hibernate: | ||
| format_sql: true | ||
| use_sql_comments: true | ||
|
|
||
| security: | ||
| oauth2: | ||
| client: | ||
| registration: | ||
| google: | ||
| redirect-uri: ${GOOGLE_REDIRECT_URI:http://localhost:8080/login/oauth2/code/google} | ||
| client-id: ${GOOGLE_CLIENT_ID:local-google-client-id} | ||
| client-secret: ${GOOGLE_CLIENT_SECRET:local-google-client-secret} | ||
| scope: | ||
| - profile | ||
| client-name: linkiving | ||
| authorization-grant-type: authorization_code | ||
|
|
||
| cloud: | ||
| aws: | ||
| s3: | ||
| bucket: ${AWS_S3_BUCKET:linkiving-local} | ||
| credentials: | ||
| access-key: ${AWS_ACCESS_KEY:local-access-key} | ||
| secret-key: ${AWS_SECRET_KEY:local-secret-key} | ||
| region: | ||
| static: ${AWS_REGION:ap-northeast-2} | ||
| stack: | ||
| auto: false | ||
|
|
||
| logging: | ||
| level: | ||
| org.hibernate.SQL: debug | ||
| org.hibernate.orm.jdbc.bind: trace | ||
|
|
||
| security: | ||
| jwt: | ||
| secret: ${JWT_SECRET:local-jwt-secret-local-jwt-secret-local-jwt-secret-local-jwt-secret} | ||
| access-token-valid-minute: 60 | ||
| refresh-token-valid-month: 6 | ||
|
|
||
| app: | ||
| oauth2: | ||
| success-redirect-url: http://localhost:3000/home | ||
| failure-redirect-url: http://localhost:3000/ | ||
| cors: | ||
| allowed-origins: | ||
| - http://localhost:3000 | ||
| extension-allowed-origins: | ||
| - ${CHROME_EXTENSION_ORIGIN:chrome-extension://replace-me} | ||
| cookie: | ||
| domain: ${COOKIE_DOMAIN:} | ||
| link: | ||
| default-image-url: ${DEFAULT_IMAGE_URL:https://linkiving-s3.s3.ap-northeast-2.amazonaws.com/static/default-thumbnail.png} | ||
|
|
||
| feign: | ||
| client: | ||
| config: | ||
| default: | ||
| connectTimeout: 5000 | ||
| readTimeout: 5000 | ||
| loggerLevel: FULL | ||
|
|
||
| summary: | ||
| worker: | ||
| sleep-duration: 1s | ||
|
|
||
| ai: | ||
| server: | ||
| url: ${AI_SERVER_URL:http://api.linkiving.com:5678} | ||
|
|
||
| linkiving: | ||
| default-image: | ||
| url: "https://linkiving-s3.s3.ap-northeast-2.amazonaws.com/static/default-thumbnail.png" | ||
| EOF |
There was a problem hiding this comment.
현재 "Create local application profile" 단계에 application-local.yml 전체가 heredoc으로 들어가 있는데, 다음과 같은 이유로 레포에 파일로 두는 방식을 제안합니다.
- 워크플로우에서 긴 heredoc이 빠져 가독성이 좋아집니다.
- 설정 변경이 diff로 보이고 버전 관리가 됩니다.
- YAML 안의 문자열 블록은 변경 추적이 어렵습니다
- IDE에서 YAML 문법 검사·하이라이팅이 적용됩니다.
- 로컬 번들을 받은 사람이 설정을 직접 열어볼 수 있어, "투명한 로컬 실행"이라는 번들 목적과도 맞습니다.
위치는 prepare-local-bundle.sh가 이미 템플릿을 가져오는 docker/local-bundle/이 일관될 것 같습니다.
참고로 PR 비고에 .gitignore 예외를 추가하셨던데, 새로 두는 application-local.yml도 해당 예외에 포함되어 추적되는지 확인이 필요해 보입니다.
| run: | | |
| mkdir -p ./src/main/resources | |
| cat <<'EOF' > ./src/main/resources/application-local.yml | |
| spring: | |
| datasource: | |
| driver-class-name: org.postgresql.Driver | |
| url: ${DB_URL:jdbc:postgresql://localhost:5432/linkiving_local} | |
| username: ${DB_USERNAME:linkiving} | |
| password: ${DB_PASSWORD:linkiving} | |
| data: | |
| redis: | |
| host: ${REDIS_HOST:localhost} | |
| port: ${REDIS_PORT:6379} | |
| ssl: | |
| enabled: ${REDIS_SSL_ENABLED:false} | |
| repositories: | |
| enabled: false | |
| jpa: | |
| database: postgresql | |
| hibernate: | |
| ddl-auto: update | |
| show-sql: true | |
| open-in-view: false | |
| properties: | |
| hibernate: | |
| format_sql: true | |
| use_sql_comments: true | |
| security: | |
| oauth2: | |
| client: | |
| registration: | |
| google: | |
| redirect-uri: ${GOOGLE_REDIRECT_URI:http://localhost:8080/login/oauth2/code/google} | |
| client-id: ${GOOGLE_CLIENT_ID:local-google-client-id} | |
| client-secret: ${GOOGLE_CLIENT_SECRET:local-google-client-secret} | |
| scope: | |
| - profile | |
| client-name: linkiving | |
| authorization-grant-type: authorization_code | |
| cloud: | |
| aws: | |
| s3: | |
| bucket: ${AWS_S3_BUCKET:linkiving-local} | |
| credentials: | |
| access-key: ${AWS_ACCESS_KEY:local-access-key} | |
| secret-key: ${AWS_SECRET_KEY:local-secret-key} | |
| region: | |
| static: ${AWS_REGION:ap-northeast-2} | |
| stack: | |
| auto: false | |
| logging: | |
| level: | |
| org.hibernate.SQL: debug | |
| org.hibernate.orm.jdbc.bind: trace | |
| security: | |
| jwt: | |
| secret: ${JWT_SECRET:local-jwt-secret-local-jwt-secret-local-jwt-secret-local-jwt-secret} | |
| access-token-valid-minute: 60 | |
| refresh-token-valid-month: 6 | |
| app: | |
| oauth2: | |
| success-redirect-url: http://localhost:3000/home | |
| failure-redirect-url: http://localhost:3000/ | |
| cors: | |
| allowed-origins: | |
| - http://localhost:3000 | |
| extension-allowed-origins: | |
| - ${CHROME_EXTENSION_ORIGIN:chrome-extension://replace-me} | |
| cookie: | |
| domain: ${COOKIE_DOMAIN:} | |
| link: | |
| default-image-url: ${DEFAULT_IMAGE_URL:https://linkiving-s3.s3.ap-northeast-2.amazonaws.com/static/default-thumbnail.png} | |
| feign: | |
| client: | |
| config: | |
| default: | |
| connectTimeout: 5000 | |
| readTimeout: 5000 | |
| loggerLevel: FULL | |
| summary: | |
| worker: | |
| sleep-duration: 1s | |
| ai: | |
| server: | |
| url: ${AI_SERVER_URL:http://api.linkiving.com:5678} | |
| linkiving: | |
| default-image: | |
| url: "https://linkiving-s3.s3.ap-northeast-2.amazonaws.com/static/default-thumbnail.png" | |
| EOF | |
| - name: 🗂️ Create local application profile | |
| run: | | |
| mkdir -p ./src/main/resources | |
| cp ./docker/local-bundle/application-local.yml ./src/main/resources/application-local.yml |
관련 이슈
PR 설명
main/ PR 기준 워크플로우를 로컬 Docker bundle artifact 생성 흐름으로 분리했습니다.v*) 기준으로만 AWS 배포와 GitHub Release 생성을 수행하는release.yml을 추가했습니다.비고
.gitignore에서 워크플로우/로컬 bundle 템플릿용yml파일이 추적되도록 예외를 추가했습니다.