깃허브에서 pull request, push 등의 이벤트가 발생하면 자동화된 작업을 수행할 수 있게 해주는 기능입니다. 카테캠 3단계에서 빌드 테스트를 진행하기 위해 사용했었습니다.
문제가 발생한 지점은, JWT 토큰의 secret과 토스 결제의 secret을 내부적으로만 사용할 수 있도록 분리해야 했습니다. 이를 위해 resources 폴더 내에 환경변수용 yaml 파일을 만들고, 값을 불러오도록 작성하였습니다.
파일은 아래처럼 작성하였습니다.
security:
jwt-config:
secret:
access: ${JWT_ACCESS_SECRET}
refresh: ${JWT_REFRESH_SECRET}
payment:
toss:
secret: ${TOSS_PAYMENT_SECRET}
이렇게 작성 후, IntelliJ에서 configuration 설정을 통해 환경변수로 해당 값들을 주입하였습니다. 그리고 spring boot 프로젝트 내에서 위 yaml 파일의 값을 읽을 수 있도록 config 파일을 추가로 작성하였습니다.
public class EnvConfig implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
YamlPropertiesFactoryBean factoryBean = new YamlPropertiesFactoryBean();
factoryBean.setResources(resource.getResource());
Properties properties = factoryBean.getObject();
assert properties != null;
return new PropertiesPropertySource(Objects.requireNonNull(resource.getResource().getFilename()), properties);
}
}
이후 application 파일에 프로퍼티 소스를 등록해줍니다.
@SpringBootApplication
@PropertySource(value = {"classpath:env/env.yaml"},
factory = EnvConfig.class)
public class SunsuWeddingApplication {
public static void main(String[] args) {
SpringApplication.run(SunsuWeddingApplication.class, args);
}
}
완료!
위에서 환경변수를 분리하였으니, 내부 값도 변경할 차례입니다.
@Value("${security.jwt-config.secret.access}")
public String ACCESS_TOKEN_SECRET;
@Value("${security.jwt-config.secret.refresh}")
private String REFRESH_TOKEN_SECRET;
이렇게 작성하면 외부 환경변수로 값 주입 완료!
환경변수를 등록해줘야 했습니다. 그래저 저희는 secret을 통해 환경변수 값을 추가하고, ci 설정 파일에서 환경변수를 주입하였습니다.
우선 GitHub repository > settings > security > secrets and variables > new repository secret 을 통해 필요한 값들을 등록합니다. 이후 ci 파일을 수정해야 하는데,
env:
JWT_ACCESS_SECRET: ${{secrets.JWT_ACCESS_SECRET}}
JWT_REFRESH_SECRET: ${{secrets.JWT_REFRESH_SECRET}}
TOSS_PAYMENT_SECRET: ${{secrets.TOSS_PAYMENT_SECRET}}
전역으로 선언했습니다!! 대부분의 구글 포스트를 보면, echo ~~ >> ~~ 이런식으로 빈 파일에 secret을 직접 작성하여 사용하는 방식이었습니다. 이렇게 되면,
결국 모든 내용은 변수가 많아지면 너무 번거롭다는 것 ... 이고 그리고 애초에 머신 내의 환경변수로 설정해두면 불필요한 코드를 적을 필요도 없고 ... 뭐랄까 빌드 테스트를 할 때 환경변수를 작성하는게 옳지 않다는 생각이 들었습니다. 필요한 구조를 설계해두고, 말단의 값만 주입하는게 맞지 않을까요? 값 주입과 동시에 파일 구조도 주입되는 것은 위험하다는 판단이 들었습니다.
아무튼 ..
깃허브를 통해 등록한 secret은 secrets.XXXX 이렇게 불러올 수 있기 때문에, env.yaml에 필요한 JWT_ACCESS_SECRET
, JWT_REFRESH_SECRET
, TOSS_PAYMENT_SECRET
이 3가지를 선언했습니다.
그리고 run
을 하면 무조건 실패!! 합니다 왜냐하면 테스트 코드를 실행할 땐 위에 내용이 주입되지 않기 때문입니다. 실행 환경과 격리되기 때문에.. 그래서 @TestPropertySource
어노테이션을 통해 테스트용 변수를 별도로 주입했습니다.
@TestPropertySource(properties = {
"security.jwt-config.secret.access=your-test-access-secret",
"security.jwt-config.secret.refresh=your-test-refresh-secret",
"payment.toss.secret=your-test-toss-payment-secret"
})
그리고 Push 후 다시 Action을 살펴보면
테스트 코드 및 실행도 모두 성공!!
땀 삐질삐질 과정 완료 ... 이제 남은건 리팩토링 ...??