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;


참고자료


Environment and Prerequisite

  • MySQL


Background

  • Thinking about ways to avoid making mistakes while using a database, I came up with the following ideas


START TRANSACTION, COMMIT, and ROLLBACK Statements

START TRANSACTION

  • Start a new transaction.
  • Remember the queries until COMMIT or ROLLBACK.

COMMIT

  • Commits the current transaction, making its changes permanent.
  • The cases that trigger implicit commits can be found in the link.

ROLLBACK

  • Rolls back the current transaction, canceling its changes.
  • Statements that cannot be rolled back can be referred to in the link.


Usage

  • An example of mistakenly modifying the values of the row with id 2 in the example_table and then correcting it by updating the values of the row with id 3.
  • In addition, TRANSACTION can be used effectively when many changes are needed in the database.
START TRANSACTION;
UPDATE example_table SET status = 'family' WHERE id = 2;
ROLLBACK;
START TRANSACTION;
UPDATE example_table SET status = 'family' WHERE id = 3;
COMMIT;


Reference

시퀀스 다이어그램(Sequence Diagram)


환경

  • UML


시퀀스 다이어그램(Sequence Diagram)

시퀀스 다이어그램(Sequence Diagram)

  • 시퀀스 다이어그램(Sequence Diagram): 객체들의 상호작용을 시간에 따라 표현한 UML 다이어그램

시퀀스 다이어그램(Sequence Diagram) 기본 표기법

  • 객체(Object): 시퀀스 다이어그램에서 상호작용하는 개체(객체 또는 클래스)로 각 객체는 다이어그램 상단에 배치되며 수평선으로 이어진 생명선이 있다.
  • 생명선(Lifeline): 객체의 존재와 상호작용이 시간에 따라 어떻게 이어지는지를 나타내는 점선으로 객체의 생명주기를 표현하며 시간은 위에서 아래로 흐른다. 활성화 된 경우에는 직사각형으로 표시된다.
  • 메시지(Message): 객체들의 상호작용에 사용하는 요청 또는 응답으로 화살표로 표시된다.

메시지 유형

  • 동기 메시지: Sender가 요청 후 응답 메시지를 받을 때까지 기다린다. 아래 그림처럼 화살표로 표시된다.
  • 비동기 메시지: Sender가 요청 후 응답 메시지를 기다리지 않고 계속 하던 작업을 진행한다. 아래 그림처럼 화살표가 표시된다.
  • 반환 메시지: 아래처럼 표시되며 불분명할 때는 생략 가능하다.


Combined Fragments

Guards

객체 간 소통 흐름을 표시할 때 조건을 이용해 흐름 제어를 하는 부분을 Guards라고 한다. 아래 IBM 문서에서는 “[pastDueBalance = 0]”로 나와있다.

Combined Fragments

시퀀스 다이어그램에서 흐름을 제어할 때 사용하는 여러 조건들이 있는데 아래와 같이 여러가지가 있다.

  • Branches and Loops
    • alt
    • opt
    • loop
    • break
  • Concurrency and Order
    • seq
    • strict
    • par
    • critical
  • Filters and Assertions
    • ignore
    • consider
    • assert
    • neg

alt, opt

  • alt: switch문으로 생각하면 되며 여러 조건을 명시해 흐름을 제어할 수 있다.
  • opt: if문으로 생각하면 되며 하나의 특정 조건에 따른 흐름을 제어할 수 있다.

loop

  • loop: 조건에 따른 반복문을 사용해 흐름을 제어할 수 있다.
  • 아래의 경우 “[size<0]”을 만족하면 5부터 10까지 반복하는 경우다.

break

  • break: 코드에서 exception과 같은 부분으로 조건을 만족하면 해당 fragment를 수행하고 기존에 남은 부분들을 수행하지 않고 바깥 fragment를 빠져나간다.
  • 만약 아래의 경우에서 break fragment 아래 다른 내용들이 더 있었다면 해당 내용을 수행하지 않고 loop를 빠져나간다.

seq, strict

  • seq: 기본으로 탑재되는 fragment로 기본 순서라 보면 된다.
  • strict: 점선으로 나눠진 부분이 차례로 실행되어야 하는 분명한 순서가 존재하는 fragment다.

관련한 좋은 그림이 있어서 다른 블로그에서 가져왔다. seq와 strict의 차이를 알 수 있다. 마지막 그림의 경우 search_google() → search_bing() → search_yahoo() 순서다.

par

  • par: parallel의 앞 글자로 말 그대로 병렬로 수행할 수 있는 걸 표현할 때 쓸 수 있다.
  • 점선으로 나누어진 fragment별로 상호 간섭 없이 독립적으로 실행될 수 있다.
  • 어떤 문서에서는 실제 parallelism은 아니고 concurrency라고 표현한 걸 봤다.
  • 아래의 그림에서 add()와 remove()를 parallel하게 요청한다고 볼 수 있다.

critical

  • critical: Atomic Area로 상호작용을 독점적으로 실행하고, 다른 요소들의 간섭을 방지할 때 사용한다.
  • 해당 critical fragment 안에서의 순서는 기본 값인 seq와 동일하다.
  • critical fragment에 들어온 경우에는 다른 메시지 상호작용이나 인터럽트 없이 해당 구역을 다 우선 수행하고 진행한다고 보면 된다.
  • 아래의 그림의 경우 add()와 remove()가 순서 관계 없이 add()→remove() 또는 remove()→add() 이렇게 진행될 수 있지만 critical fragment에서는 둘 중 하나만 실행하고 다음 요청을 처리한다.

ignore

  • ignore: 특정 유형의 메시지들을 무시하기 위해 사용한다.
  • {} 안에 무시할 메시지를 명시한다.
  • 아래의 경우 명시된 get과 set이 무시된다.

consider

  • consider: 특정 유형의 메시지들을 표시하고 강조하고 나머지는 무시하기 위해 사용한다.
  • {} 안에 강조하거나 표시할 메시지를 명시한다.
  • 아래의 경우 add와 remove만 고려하고 다른 메시지는 무시한다고 보면 된다.

assert

  • assert: 항상 참이어야 하는 상호작용의 일부를 정의하는 데 사용된다고 한다.
  • {}로 조건이 명시되기도 하는데 해당 조건을 반드시 만족해야 한다.

neg

  • neg: 유효하지 않거나 오류가 난 경우를 표현하기 위해 사용한다.
  • neg가 아닌 모든 부분들은 정상 작동된 경우로 가정한다.
  • 아래의 경우 timeout이 난 경우에는 잘못된 경우라는 표현이다.


기타

Reference

  • 하나의 시퀀스 다이어그램과 다른 시퀀스 다이어그램을 연결할 때 사용하는 방법이다. ref 안에 다른 시퀀스 다이어그램이 존재한다고 보면 된다.

참고자료