Home > 기타 > (CI/CD) Github Actions Secret의 JSON 파일 저장 오류

(CI/CD) Github Actions Secret의 JSON 파일 저장 오류
java

구글 인앱결제 서비스 로직을 구현할 때 겪은 오류이다.

1. 오류 발생 상황

전체 코드

// InAppPurchaseService.java
@Service
public class InAppPurchaseService {

  @Value("${google-account.file-path}")
  private String googleAccountFilePath;

  @Value("${google-application.package-name}")
  private String googleApplicationPackageName;

  @Transactional
  public Boolean validateReceipt(Long userId, PurchaseRequest purchaseRequest) {
    HttpTransport httpTransport;
    GoogleCredentials credentials;
    try {
      httpTransport = GoogleNetHttpTransport.newTrustedTransport();
      InputStream inputStream = new ClassPathResource(googleAccountFilePath).getInputStream();
      credentials = GoogleCredentials
	  		.fromStream(inputStream)
			.createScoped(AndroidPublisherScopes.ANDROIDPUBLISHER);
    } catch (IOException | GeneralSecurityException e) {
      throw ExpectedException.withLogging(ResponseCode.GoogleCredentialException, e);	
    }
	
    AndroidPublisher.Builder builder = new AndroidPublisher.Builder(httpTransport, 
					GsonFactory.getDefaultInstance(), 
					new HttpCredentialsAdapter(credentials));
    AndroidPublisher publisher = builder.setApplicationName(googleApplicationPackageName).build();
    //...(중략)
  }
}
# ci-cd.yml
jobs:
  CI-CD:
    runs-on: ubuntu-22.04
    steps:
	# ...(중략)
      - name: Create Google key.json file
	if: contains(github.ref, 'main') || contains(github.ref, 'staging')
	run: |
	  cd ./genti-api/src/main/resources
  	  mkdir -p ./jsonkey
	  echo "${secrets.GOOGLE_ACCOUNT_KEY }" > ./jsonkey/key.json
	shell: bash
	# ...(중략)

오류 메세지

  • com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 2 column 4 path $.

2. 오류 분석

코드 오류 부분

// InAppPurchaseService.java
public Boolean validateReceipt(Long userId, PurchaseRequest purchaseRequest) {
  //...
  try {
    //...
    credentials = GoogleCredentials
		.fromStream(inputStream)  // 오류 발생 부분
		.createScoped(AndroidPublisherScopes.ANDROIDPUBLISHER);
  }
  //...
}

오류 분석

  1. 오류 메시지를 보면, JSON 파싱 중 문제가 있다고 한다. 로컬에서는 발생하지 않던 오류라서, 서버 측에 저장되는 JSON 파일에 문제가 있을 것으로 추측했다.

  2. 따라서, 서버 측에 저장되는 JSON 파일을 확인하기 위해 해당 JSON 파일을 S3에 저장하는 부분을 ci-cd.yml에 임시로 추가했다.
    - name: Upload key.json to S3
      if: contains(github.ref, 'staging')
      run: |
       aws s3 cp ./genti-api/src/main/resources/jsonkey/key.json s3://$S3_BUCKET_NAME/jsonkey/key.json
    
  3. S3에서 key.json 파일을 다운받아 확인해보았더니, 아래처럼 큰따옴표가 다 사라져 있었다.
     {
       type: service_account,
       project_id: example,
       (...)
     }
    
  4. 결론 - 오류의 원인
    • Github Actions Secret에 JSON 파일 내용을 넣으면 JSON 파일 내용의 큰따옴표가 다 사라지게 된다.

3. 오류 해결

create-json 라이브러리 사용

# ci-cd.yml
- name: Create jsonkey directory
  if: contains(github.ref, 'main') || contains(github.ref, 'staging')
  run: mkdir -p ./genti-api/src/main/resources/jsonkey

- name: Create Google key.json file
  if: contains(github.ref, 'main') || contains(github.ref, 'staging')  
  id: create-json
  uses: jsdaniell/create-json@1.1.2
  with:
    name: "./genti-api/src/main/resources/jsonkey/key.json"
    json: ${ secrets.GOOGLE_ACCOUNT_KEY }

  • 참조 자료
    https://stackoverflow.com/questions/11484353/gson-throws-malformedjsonexception
    https://choo.oopy.io/fd2d4fc6-21ac-45b6-bd0c-05768920bb00
    https://roel-yomojomo.tistory.com/38
    https://velog.io/@godkimchichi/Github-Actions-secret%EC%97%90-json-%EB%84%A3%EA%B3%A0-%EC%8B%B6%EC%9D%84-%EB%95%8C