diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 72adff2..1de509f 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,106 +1,106 @@ name: release run-name: release ${{ github.actor }} on: - push: - tags: - - "version-[0-9]+.[0-9]+.[0-9]+" - workflow_dispatch: + push: + tags: + - "version-[0-9]+.[0-9]+.[0-9]+" + workflow_dispatch: env: - REGISTRY: docker.frappet.com - IMAGE_NAME: ehr/bma-ehr-recruit-service - DEPLOY_HOST: frappet.com - COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-recruit + REGISTRY: docker.frappet.com + IMAGE_NAME: ehr/bma-ehr-recruit-service + DEPLOY_HOST: frappet.com + COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-recruit jobs: - # act workflow_dispatch -W .github/workflows/release.yaml --input IMAGE_VER=latest -s DOCKER_USER=admin -s DOCKER_PASS=FPTadmin2357 -s SSH_PASSWORD=FPTadmin2357 - release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - # skip Set up QEMU because it fail on act and container - # Gen Version try to get version from tag or inut - - name: Set output tags - id: vars - run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT - - name: Gen Version - id: gen_ver - run: | - if [[ $GITHUB_REF == 'refs/tags/'* ]]; then - IMAGE_VER=${{ steps.vars.outputs.tag }} - else - IMAGE_VER=${{ github.event.inputs.IMAGE_VER }} - fi - if [[ $IMAGE_VER == '' ]]; then - IMAGE_VER='test-vBeta' - fi - echo '::set-output name=image_ver::'$IMAGE_VER - - name: Check Version - run: | - echo $GITHUB_REF - echo ${{ steps.gen_ver.outputs.image_ver }} + # act workflow_dispatch -W .github/workflows/release.yaml --input IMAGE_VER=latest -s DOCKER_USER=admin -s DOCKER_PASS=FPTadmin2357 -s SSH_PASSWORD=FPTadmin2357 + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + # skip Set up QEMU because it fail on act and container + # Gen Version try to get version from tag or inut + - name: Set output tags + id: vars + run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT + - name: Gen Version + id: gen_ver + run: | + if [[ $GITHUB_REF == 'refs/tags/'* ]]; then + IMAGE_VER=${{ steps.vars.outputs.tag }} + else + IMAGE_VER=${{ github.event.inputs.IMAGE_VER }} + fi + if [[ $IMAGE_VER == '' ]]; then + IMAGE_VER='test-vBeta' + fi + echo '::set-output name=image_ver::'$IMAGE_VER + - name: Check Version + run: | + echo $GITHUB_REF + echo ${{ steps.gen_ver.outputs.image_ver }} - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - name: Login in to registry - uses: docker/login-action@v2 - with: - registry: ${{env.REGISTRY}} - username: ${{secrets.DOCKER_USER}} - password: ${{secrets.DOCKER_PASS}} - - name: Build and push docker image - uses: docker/build-push-action@v3 - with: - context: . - platforms: linux/amd64 - push: true - tags: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}:${{ steps.gen_ver.outputs.image_ver }},${{env.REGISTRY}}/${{env.IMAGE_NAME}}:latest + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Login in to registry + uses: docker/login-action@v2 + with: + registry: ${{env.REGISTRY}} + username: ${{secrets.DOCKER_USER}} + password: ${{secrets.DOCKER_PASS}} + - name: Build and push docker image + uses: docker/build-push-action@v3 + with: + context: . + platforms: linux/amd64 + push: true + tags: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}:${{ steps.gen_ver.outputs.image_ver }},${{env.REGISTRY}}/${{env.IMAGE_NAME}}:latest - - name: Reload docker compose - uses: appleboy/ssh-action@v0.1.8 - with: - host: ${{env.DEPLOY_HOST}} - username: frappet - password: ${{ secrets.SSH_PASSWORD }} - port: 10102 - script: | - cd "${{env.COMPOSE_PATH}}" - docker compose pull - docker compose up -d - echo "${{ steps.gen_ver.outputs.image_ver }}"> success - - name: Notify Discord Success - if: success() - run: | - curl -H "Content-Type: application/json" \ - -X POST \ - -d '{ - "embeds": [{ - "title": "✅ Deployment Success!", - "description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Deployed by: `${{github.actor}}`", - "color": 3066993, - "footer": { - "text": "Release Notification", - "icon_url": "https://example.com/success-icon.png" - }, - "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'" - }] - }' \ - ${{ secrets.DISCORD_WEBHOOK }} + - name: Reload docker compose + uses: appleboy/ssh-action@v0.1.8 + with: + host: ${{env.DEPLOY_HOST}} + username: frappet + password: ${{ secrets.SSH_PASSWORD }} + port: 10102 + script: | + cd "${{env.COMPOSE_PATH}}" + docker compose pull + docker compose up -d + echo "${{ steps.gen_ver.outputs.image_ver }}"> success + # - name: Notify Discord Success + # if: success() + # run: | + # curl -H "Content-Type: application/json" \ + # -X POST \ + # -d '{ + # "embeds": [{ + # "title": "✅ Deployment Success!", + # "description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Deployed by: `${{github.actor}}`", + # "color": 3066993, + # "footer": { + # "text": "Release Notification", + # "icon_url": "https://example.com/success-icon.png" + # }, + # "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'" + # }] + # }' \ + # ${{ secrets.DISCORD_WEBHOOK }} - - name: Notify Discord Failure - if: failure() - run: | - curl -H "Content-Type: application/json" \ - -X POST \ - -d '{ - "embeds": [{ - "title": "❌ Deployment Failed!", - "description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Attempted by: `${{github.actor}}`", - "color": 15158332, - "footer": { - "text": "Release Notification", - "icon_url": "https://example.com/failure-icon.png" - }, - "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'" - }] - }' \ - ${{ secrets.DISCORD_WEBHOOK }} + # - name: Notify Discord Failure + # if: failure() + # run: | + # curl -H "Content-Type: application/json" \ + # -X POST \ + # -d '{ + # "embeds": [{ + # "title": "❌ Deployment Failed!", + # "description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Attempted by: `${{github.actor}}`", + # "color": 15158332, + # "footer": { + # "text": "Release Notification", + # "icon_url": "https://example.com/failure-icon.png" + # }, + # "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'" + # }] + # }' \ + # ${{ secrets.DISCORD_WEBHOOK }} diff --git a/Services/RecruitService.cs b/Services/RecruitService.cs index af83564..a304cfd 100644 --- a/Services/RecruitService.cs +++ b/Services/RecruitService.cs @@ -183,19 +183,26 @@ namespace BMA.EHR.Recruit.Service.Services // 🚀 Prepare HTTP client once var httpClient1 = new HttpClient(); httpClient1.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token?.Replace("Bearer ", "")); + Console.WriteLine("118"); httpClient1.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]); + Console.WriteLine("117"); var apiUrl1 = $"{_configuration["API"]}/api/v1/org/pos/level"; + Console.WriteLine("116"); var response1 = await httpClient1.GetStringAsync(apiUrl1); + Console.WriteLine("115"); var posOptions = JsonConvert.DeserializeObject(response1); + Console.WriteLine("114"); var recruitImport = await _context.RecruitImports.AsQueryable() .FirstOrDefaultAsync(x => x.Id == examId); + Console.WriteLine("113"); if (recruitImport == null) throw new Exception(GlobalMessages.DataNotFound); var _placement = await _contextMetadata.Placements.AsQueryable() .FirstOrDefaultAsync(x => x.PlacementType.Name == "สอบแข่งขัน" && x.RefId == recruitImport.Id); + Console.WriteLine("112"); // if (_placement != null) // throw new Exception("รอบการสอบนี้ได้ทำการบรรจุไปแล้ว"); @@ -205,6 +212,7 @@ namespace BMA.EHR.Recruit.Service.Services var districtsCache = await _contextOrg.district.ToListAsync(); var subDistrictsCache = await _contextOrg.subDistrict.ToListAsync(); var educationLevelsCache = await _contextOrg.educationLevel.ToListAsync(); + Console.WriteLine("101"); var placement = new Placement { @@ -224,6 +232,7 @@ namespace BMA.EHR.Recruit.Service.Services LastUpdateFullName = FullName ?? "", }; await _contextMetadata.Placements.AddAsync(placement); + Console.WriteLine("191"); // 🚀 Load all related data with single queries var candidates = await _context.Recruits.AsQueryable() @@ -250,6 +259,7 @@ namespace BMA.EHR.Recruit.Service.Services httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token?.Replace("Bearer ", "")); httpClient.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]); + Console.WriteLine("181"); // 🚀 Batch HTTP requests var orgTasks = candidates.Select(async candidate => { @@ -267,6 +277,7 @@ namespace BMA.EHR.Recruit.Service.Services return new { CitizenId = candidate.CitizenId ?? "", org = (dynamic?)null }; } }).ToList(); + Console.WriteLine("171"); var orgResults = await Task.WhenAll(orgTasks); var orgDict = orgResults.ToDictionary(x => x.CitizenId ?? "", x => x.org); @@ -275,6 +286,7 @@ namespace BMA.EHR.Recruit.Service.Services var placementProfiles = new List(); var placementEducations = new List(); var placementCertificates = new List(); + Console.WriteLine("161"); foreach (var candidate in candidates) { @@ -433,12 +445,17 @@ namespace BMA.EHR.Recruit.Service.Services LastUpdateFullName = FullName ?? "", }; placementCertificates.Add(placementCertificate); + Console.WriteLine("511"); } + Console.WriteLine("141"); // 🚀 Batch insert all records await _contextMetadata.PlacementProfiles.AddRangeAsync(placementProfiles); + Console.WriteLine("131"); await _contextMetadata.PlacementEducations.AddRangeAsync(placementEducations); + Console.WriteLine("121"); await _contextMetadata.PlacementCertificates.AddRangeAsync(placementCertificates); + Console.WriteLine("111"); // 🚀 Single SaveChanges at the end await _contextMetadata.SaveChangesAsync();