name: Publish Baron SSO Production Images on: workflow_dispatch: inputs: version_prefix: description: "공용 저장소 이미지 태그 prefix (예: v1.2606, 최종 태그는 v1.2606.<커밋해시4자리>)" required: true type: string jobs: publish-images: runs-on: ubuntu-latest steps: - name: Checkout dev branch uses: actions/checkout@v4 with: ref: dev - name: Validate publish inputs env: VERSION_PREFIX: ${{ github.event.inputs.version_prefix }} HARBOR_ENDPOINT: ${{ vars.HARBOR_ENDPOINT }} HARBOR_HOSTNAME: ${{ vars.HARBOR_HOSTNAME }} HARBOR_ROBOT_ACCOUNT: ${{ vars.HARBOR_ROBOT_ACCOUNT }} HARBOR_ROBOT_KEY: ${{ secrets.HARBOR_ROBOT_KEY }} ADMINFRONT_URL: ${{ vars.ADMINFRONT_URL }} DEVFRONT_URL: ${{ vars.DEVFRONT_URL }} ORGFRONT_URL: ${{ vars.ORGFRONT_URL }} VITE_OIDC_AUTHORITY: ${{ vars.VITE_OIDC_AUTHORITY }} run: | set -euo pipefail if ! printf '%s' "${VERSION_PREFIX}" | grep -Eq '^v[0-9]+\.[0-9]{4}$'; then echo "::error::version_prefix must look like vX.YYMM (got: ${VERSION_PREFIX})" exit 1 fi required_values=" HARBOR_ENDPOINT HARBOR_HOSTNAME HARBOR_ROBOT_ACCOUNT HARBOR_ROBOT_KEY ADMINFRONT_URL DEVFRONT_URL ORGFRONT_URL VITE_OIDC_AUTHORITY " for key in ${required_values}; do if [ -z "${!key:-}" ]; then echo "::error::Missing required publish value: ${key}. Check Gitea repo variables/secrets." exit 1 fi done - name: Compute commit-hash image tag id: version env: VERSION_PREFIX: ${{ github.event.inputs.version_prefix }} run: | set -euo pipefail short_sha="$(git rev-parse --short=4 HEAD)" if ! printf '%s' "${short_sha}" | grep -Eq '^[0-9a-f]{4}$'; then echo "::error::commit hash suffix must be 4 lowercase hexadecimal characters (got: ${short_sha})" exit 1 fi image_tag="${VERSION_PREFIX}.${short_sha}" echo "image_tag=${image_tag}" >> "${GITHUB_OUTPUT}" echo "Computed production image tag: ${image_tag}" - name: Login to shared registry uses: docker/login-action@v3 with: registry: ${{ vars.HARBOR_ENDPOINT }} username: ${{ vars.HARBOR_ROBOT_ACCOUNT }} password: ${{ secrets.HARBOR_ROBOT_KEY }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build and push backend production image uses: docker/build-push-action@v5 with: context: ./backend file: ./backend/Dockerfile push: true tags: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/backend:${{ steps.version.outputs.image_tag }} provenance: false sbom: false - name: Build and push userfront production image uses: docker/build-push-action@v5 with: context: . file: ./userfront/Dockerfile target: production push: true tags: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/userfront:${{ steps.version.outputs.image_tag }} provenance: false sbom: false - name: Build and push adminfront production image uses: docker/build-push-action@v5 with: context: . file: ./adminfront/Dockerfile target: production push: true tags: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/adminfront:${{ steps.version.outputs.image_tag }} build-args: | VITE_ADMIN_PUBLIC_URL=${{ vars.ADMINFRONT_URL }} VITE_OIDC_AUTHORITY=${{ vars.VITE_OIDC_AUTHORITY }} VITE_OIDC_CLIENT_ID=adminfront ORGFRONT_URL=${{ vars.ORGFRONT_URL }} provenance: false sbom: false - name: Build and push devfront production image uses: docker/build-push-action@v5 with: context: . file: ./devfront/Dockerfile target: production push: true tags: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/devfront:${{ steps.version.outputs.image_tag }} build-args: | VITE_DEVFRONT_PUBLIC_URL=${{ vars.DEVFRONT_URL }} VITE_OIDC_AUTHORITY=${{ vars.VITE_OIDC_AUTHORITY }} VITE_OIDC_CLIENT_ID=devfront ORGFRONT_URL=${{ vars.ORGFRONT_URL }} provenance: false sbom: false - name: Build and push orgfront production image uses: docker/build-push-action@v5 with: context: . file: ./orgfront/Dockerfile target: production push: true tags: ${{ vars.HARBOR_HOSTNAME }}/baron_sso/orgfront:${{ steps.version.outputs.image_tag }} build-args: | VITE_ORGFRONT_PUBLIC_URL=${{ vars.ORGFRONT_URL }} VITE_OIDC_AUTHORITY=${{ vars.VITE_OIDC_AUTHORITY }} VITE_OIDC_CLIENT_ID=orgfront provenance: false sbom: false - name: Upload pushed images to WORKS Drive archive if: ${{ vars.WORKS_DRIVE_DOCKER_IMAGE_ARCHIVE_ENABLED == 'true' }} env: IMAGE_TAG: ${{ steps.version.outputs.image_tag }} HARBOR_HOSTNAME: ${{ vars.HARBOR_HOSTNAME }} WORKS_SHAREDRIVE_DOCKER_IMAGE_DIR: ${{ vars.WORKS_SHAREDRIVE_DOCKER_IMAGE_DIR }} WORKS_DRIVE_TARGET: sharedrive WORKS_DRIVE_SHARED_DRIVE_ID: ${{ vars.WORKS_DRIVE_SHARED_DRIVE_ID }} WORKS_DRIVE_PARENT_FILE_ID: ${{ vars.WORKS_DRIVE_PARENT_FILE_ID }} WORKS_DRIVE_OAUTH_CLIENT_ID: ${{ secrets.WORKS_DRIVE_OAUTH_CLIENT_ID }} WORKS_DRIVE_OAUTH_CLIENT_SECRET: ${{ secrets.WORKS_DRIVE_OAUTH_CLIENT_SECRET }} WORKS_DRIVE_OAUTH_CLIENT_SERVICE_ACCOUNT: ${{ secrets.WORKS_DRIVE_OAUTH_CLIENT_SERVICE_ACCOUNT }} WORKS_DRIVE_OAUTH_CLIENT_PRIVATE_KEY: ${{ secrets.WORKS_DRIVE_OAUTH_CLIENT_PRIVATE_KEY }} WORKS_DRIVE_OAUTH_REFRESH_TOKEN: ${{ secrets.WORKS_DRIVE_OAUTH_REFRESH_TOKEN }} WORKS_ADMIN_API_BASE_URL: ${{ vars.WORKS_ADMIN_API_BASE_URL }} WORKS_ADMIN_OAUTH_TOKEN_URL: ${{ vars.WORKS_ADMIN_OAUTH_TOKEN_URL }} run: | set -euo pipefail : "${WORKS_SHAREDRIVE_DOCKER_IMAGE_DIR:=docker-build-image}" required_values=" IMAGE_TAG HARBOR_HOSTNAME WORKS_DRIVE_SHARED_DRIVE_ID " for key in ${required_values}; do if [ -z "${!key:-}" ]; then echo "::error::Missing required WORKS image archive value: ${key}." exit 1 fi done for image in backend userfront adminfront devfront orgfront; do image_ref="${HARBOR_HOSTNAME}/baron_sso/${image}:${IMAGE_TAG}" docker pull "${image_ref}" DOCKER_IMAGE_REF="${image_ref}" \ WORKS_DOCKER_IMAGE_ARCHIVE_DIR="${RUNNER_TEMP}/baron-sso-docker-image-upload" \ scripts/docker-image/upload_works_drive.sh done