환경

  • GCP
  • GitHub Actions


GCP Console 입력에서 Audience 입력 시 있었던 일

GitHub Actions에서 GCP 인증을 위해 Workload Identity Federation을 설정할 때, Audience 값을 입력하는 부분이 있었다. 해당 값을 입력하고 GitHub Actions을 실행했더니 아래와 같은 오류가 발생했다.

Error: google-github-actions/auth failed with: retry function failed after 4 attempts: failed to generate Google Cloud federated token for ***: (400) {"error":"invalid_grant","error_description":"The audience in ID Token [***] does not match the expected audience."}

값을 복사해 붙여넣은 것이었기 때문에 Ctrl + F로 여러 번 확인했음에도 불구하고 계속 오류가 났다. 몇 시간을 시도해 본 끝에, 입력한 값 앞에 공백(“ “)이 있어서 다른 값으로 인식되고 있었다는 것을 알게 되었다.

공백을 인식하거나 경고해주는 검증이 있었더라면 좋았겠지만, 그런 기능이 없어서 공백이 포함된 채 값이 입력되었다. 물론 이 부분은 명백히 내 실수다. 예전에 회사에서 비밀번호 입력할 때도 비슷한 문제가 있었는데, 앞으로는 입력에 좀 더 주의해야겠다.


참고자료


Environment and Prerequisite

  • GCP
  • GitHub Actions


Background

While setting up Workload Identity Federation for GCP authentication in GitHub Actions, there was a step to put the Audience value. After putting the value and running the workflow, I encountered the following error.

Error: google-github-actions/auth failed with: retry function failed after 4 attempts: failed to generate Google Cloud federated token for ***: (400) {"error":"invalid_grant","error_description":"The audience in ID Token [***] does not match the expected audience."}

Since I had copied and pasted the value, I used Ctrl + F to verify it multiple times, but the error persisted. After spending a few hours troubleshooting, I finally realized that there was a space (“ “) at the beginning of the input.

It would’ve been helpful if there had been a validation check to catch or warn about leading spaces, but there wasn’t. So the value was accepted with the space included. Of course, this was entirely my fault. I had a similar issue before at work when entering a password, so from now on, I’ll be more careful about blank space in my inputs.


Reference

GitHub Actions actions/github-script에서 별도 파일을 실행하기


환경

  • GitHub Actions
  • JavaScript


배경

  • yq 혹은 코드를 통해 GitHub Actions에 있는 workflow YAML 파일을 동적으로 수정했을 때 코드가 큰따옴표(“”)로 감싸지는 현상이 있어서, 코드 파일을 바깥으로 빼고 호출하는 형태로 변경한 사례가 있어서 정리함.
  • actions/github-script를 사용해봤는데 앞으로도 종종 사용할거 같아서 정리함.


방법

  • 사용법은 공식 문서에 나와 있었다.
  • 일반적인 JavaScript의 호출 및 사용법과 같다.

예시

코드

github-script-file-return-test.yml

name: Separate JavaScript File Return Workflow
on:
  workflow_dispatch:
jobs:
  print-javascript-return-value-job:
    name: print javascript process return value
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Run javascript code
        id: workflow_result
        uses: actions/github-script@v7
        with:
          script: |
            const exportedModule = require('.github/workflows/scripts/github-script-file-test.js');
            return exportedModule.processValue(github, context);
      - name: Print javascript return value
        run: |
          echo "${{ fromJSON(steps.workflow_result.outputs.result).data }}"

github-script-file-test.js

function processValue(github, context) {
  console.log(JSON.stringify(context));
  return {"data": context.workflow};
};

module.exports = {
    processValue
};

결과

Run echo "Separate JavaScript File Return Workflow"
  echo "Separate JavaScript File Return Workflow"
  shell: /usr/bin/bash -e {0}
Separate JavaScript File Return Workflow


기타

  • 문서에 보면 사용할 수 있는 미리 만들어진 객체들이 있다.
    • github: A pre-authenticated octokit/rest.js client with pagination plugins
    • context: An object containing the context of the workflow run
    • core: A reference to the @actions/core package
    • glob: A reference to the @actions/glob package
    • io: A reference to the @actions/io package
    • exec: A reference to the @actions/exec package
    • require: A proxy wrapper around the normal Node.js require to enable requiring relative paths (relative to the - - current working directory) and requiring npm packages installed in the current working directory. If for some reason you need the non-wrapped require, there is an escape hatch available: original_require is the original value of require without our wrapping applied.
  • actions/github-script 사용시에 코드가 길어질 경우 포맷팅도 할 수 없고 관리가 어려워질거 같아서 외부 파일로 분리했다.
  • 일반 JavaScript 사용법과 사실 똑같다.


참고자료

Usage of running a separate file in GitHub Actions actions/github-script


Environment and Prerequisite

  • GitHub Actions
  • JavaScript


Background

  • I encountered an issue where code was being wrapped in double quotes (“”) when dynamically modifying workflow YAML files in GitHub Actions using yq or code so I extracted the code files and called that instead.
  • I once applied actions/github-script and since I think I’ll be using it often in the future. So I decided to write it.


Usage

  • The official document provides the instructions.
  • It is similar to the usual way of using JavaScript.

Example

Code

github-script-file-return-test.yml

name: Separate JavaScript File Return Workflow
on:
  workflow_dispatch:
jobs:
  print-javascript-return-value-job:
    name: print javascript process return value
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Run javascript code
        id: workflow_result
        uses: actions/github-script@v7
        with:
          script: |
            const exportedModule = require('.github/workflows/scripts/github-script-file-test.js');
            return exportedModule.processValue(github, context);
      - name: Print javascript return value
        run: |
          echo "${{ fromJSON(steps.workflow_result.outputs.result).data }}"

github-script-file-test.js

function processValue(github, context) {
  console.log(JSON.stringify(context));
  return {"data": context.workflow};
};

module.exports = {
    processValue
};

Result

Run echo "Separate JavaScript File Return Workflow"
  echo "Separate JavaScript File Return Workflow"
  shell: /usr/bin/bash -e {0}
Separate JavaScript File Return Workflow


Others

  • The document introduces pre-built objects that you can use.
    • github: A pre-authenticated octokit/rest.js client with pagination plugins
    • context: An object containing the context of the workflow run
    • core: A reference to the @actions/core package
    • glob: A reference to the @actions/glob package
    • io: A reference to the @actions/io package
    • exec: A reference to the @actions/exec package
    • require: A proxy wrapper around the normal Node.js require to enable requiring relative paths (relative to the - - current working directory) and requiring npm packages installed in the current working directory. If for some reason you need the non-wrapped require, there is an escape hatch available: original_require is the original value of require without our wrapping applied.
  • When using actions/github-script, I separated the code into an external file because if the code gets too long, it becomes difficult to format and manage.
  • It is actually the same as using regular JavaScript.


Reference


환경

  • MySQL


배경

  • 데이터베이스를 사용하다가 실수를 하지 않으려면 어떤 방법이 있을까 하면서 생각하다가 정리


START TRANSACTION, COMMIT, and ROLLBACK 구문들

START TRANSACTION

  • 새로운 트랜잭션을 시작
  • 이어지는 쿼리들을 다 기억한다.

COMMIT

  • 현재 트랜잭션을 커밋하여 해당 변경 사항을 영구적으로 반영한다.
  • Implicit Commit을 발생시키는 경우는 링크를 참고

ROLLBACK

  • 현재 트랜잭션을 롤백하여 해당 변경 사항들을 취소한다.
  • Rollback을 할 수 없는 구문의 경우 링크를 참고


사용 예시

  • example_table에서 실수로 id가 2인 행의 값을 잘못 변경해서 다시 id가 3인 행의 값을 변경하는 예시
  • 이 외에도 데이터베이스에 많은 변경이 필요할 때 TRANSACTION을 사용하여 유용하게 처리할 수 있다.
START TRANSACTION;
UPDATE example_table SET status = 'family' WHERE id = 2;
ROLLBACK;
START TRANSACTION;
UPDATE example_table SET status = 'family' WHERE id = 3;
COMMIT;


참고자료