scaffold

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 30, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package scaffold 는 앱 프로젝트에 커밋할 초기 파일들을 만든다.

소스와 배포 매니페스트가 한 저장소에 함께 산다. CI 가 이미지를 만들어 레지스트리에 올린 뒤 deploy/ 의 태그를 갱신해 되쓰면, Argo CD 가 그 커밋을 감지해 배포한다.

이미지 저장 위치는 이 패키지가 정하지 않는다 — port.ImageTarget 으로 받는다. GitLab 프로젝트 레지스트리를 전제하면 Harbor 스택에서 엉뚱한 곳에 올린다.

Index

Constants

View Source
const (
	// GitUsernameVar / GitPasswordVar 는 매니페스트 되커밋에 쓰는 자격증명이다.
	// ESO 가 만든 파이프라인 Secret 에서 환경변수로 들어온다.
	//
	// 자격증명을 채우는 쪽(cicd/usecase 의 configureGiteaPipeline)이 같은
	// 이름을 써야 한다 — 갈라지면 push 가 인증 실패로 죽는다.
	GitUsernameVar = "GIT_USERNAME"
	GitPasswordVar = "GIT_PASSWORD" // #nosec G101 -- CI 변수 이름
)
View Source
const (
	// InitialImageTag 는 첫 커밋 시점의 태그다. 아직 빌드된 이미지가 없으므로
	// CI 가 첫 실행에서 실제 커밋 SHA 로 치환한다.
	InitialImageTag = "bootstrap"

	// DeployTokenVar 는 GitLab CI 가 매니페스트를 되쓰기 위해 쓰는 토큰 변수다.
	// CI_JOB_TOKEN 은 저장소 push 권한이 없어 별도 토큰이 필요하다.
	//
	// GitHub 에는 대응물이 없다 — 내장 GITHUB_TOKEN 이 contents:write 로 push 한다.
	DeployTokenVar = "NULLUS_DEPLOY_TOKEN" // #nosec G101 -- CI 변수 이름

	// GitLabPipelinePath / GitHubWorkflowPath 는 각 플랫폼이 파이프라인 정의를
	// 읽는 위치다. 경로가 틀리면 파일은 커밋되지만 CI 가 영영 돌지 않는다.
	GitLabPipelinePath = ".gitlab-ci.yml"
	GitHubWorkflowPath = ".github/workflows/nullus-ci.yml"
	// JenkinsfilePath 는 Jenkins multibranch job 이 파이프라인 정의를 찾는
	// 위치다. 리포 루트가 아니면 job 이 "Jenkinsfile not found" 로 브랜치를
	// 통째로 건너뛴다.
	JenkinsfilePath = "Jenkinsfile"
)
View Source
const (

	// PreCommitConfigPath / GitleaksConfigPath 는 앱 저장소에 함께 넣는 개발자 로컬 훅 설정과
	// gitleaks 설정(오탐 allowlist)이다. 처음 만들 때만 넣고 **정의 갱신에서는 덮어쓰지 않는다** —
	// allowlist 는 사용자가 다듬는 파일이다.
	PreCommitConfigPath = ".pre-commit-config.yaml"
	GitleaksConfigPath  = ".gitleaks.toml"
)

시크릿 탐지(Secret Detection) 단계 — 사용자 저장소의 코드·이력에 섞여 들어간 자격증명· 토큰·키를 gitleaks 로 찾아 배포를 막는다(nullus-plan#80, 설계 docs/11_기능설계/ Nullus_시크릿_탐지_설계.md).

이미지 스캔·SAST 와 두 가지가 다르다.

  • 스택에 설치하는 것이 없다. 스캐너는 CI 잡 컨테이너 이미지 하나라 **모든 파이프라인에 단계가 있다** — 끄는 것은 정책(NULLUS_SECRET_DETECTION=off)이지 렌더링이 아니다.
  • 빌드 **앞**에 선다. 시크릿이 든 소스로 이미지를 만들어 레지스트리에 올리는 것부터 막아야 한다. SAST 는 빌드와 나란히 돌지만, 이 단계는 빌드가 기다린다.

그리고 한 가지가 같다 — 시크릿은 **푸시되는 순간 유출**이다. CI 단계는 사후 통보라 탐지 시 메시지에 "폐기·회전" 안내가 반드시 붙는다. 유출 전에 잡는 길은 저장소에 함께 넣는 pre-commit 훅(renderPreCommitConfig)이다 — 둘을 병행한다.

View Source
const PlatformGuidePath = "NULLUS.md"

PlatformGuidePath 는 원본을 가져온 저장소에 두는 플랫폼 안내다.

원본 README 를 덮지 않는다 — 그 프로젝트를 설명하는 문서는 원본 것이다. 흐름·변수·원본 출처는 이 파일에 따로 적는다.

Variables

This section is empty.

Functions

func CheckImportable added in v0.6.0

func CheckImportable(src *ImportedSource) error

CheckImportable 은 원본을 이 저장소의 첫 커밋으로 올릴 수 있는지 본다.

저장소를 만들기 전에 부른다. 만든 뒤에 실패하면 README 만 든 저장소가 남고, 같은 이름으로 다시 만들면 "이미 있던 저장소" 라 스캐폴딩을 건너뛴다.

func IsPipelineDefinitionPath added in v0.6.0

func IsPipelineDefinitionPath(path string) bool

Render 는 앱 프로젝트에 커밋할 파일들을 만든다.

같은 입력이면 같은 결과다 — 재스캐폴딩이 의미 없는 diff 를 만들지 않도록 파일 경로를 정렬해 돌려준다. IsPipelineDefinitionPath 는 그 파일이 CI 파이프라인 정의인지 본다 — .gitlab-ci.yml · GitHub 워크플로 · Jenkinsfile. 기존 파이프라인의 정의 갱신은 이것만 다시 쓴다. 앱 코드· Dockerfile·배포 매니페스트는 사용자 것이고, CI 가 갱신한 이미지 태그가 거기 있다.

func PipelineStageNames

func PipelineStageNames(opts StageOptions) []string

PipelineStageNames 는 스캐폴딩이 만드는 파이프라인의 단계 이름이다.

템플릿이 선언하는 stages 의 출처다. 손으로 적으면 실제와 어긋나고, 어긋나면 화면이 돌지도 않은 단계를 보여준다 — 실제로 템플릿은 Build/Test/ImageBuild/ Deploy 4단계를 선언했지만 스캐폴딩은 2단계만 만들었다.

GitLab 판과 Jenkins 판이 같은 단계를 만든다. 이름 표기만 다르므로(소문자 대 대문자) 여기서는 표시용 표기를 쓴다.

func PipelineStageNamesFor added in v0.6.0

func PipelineStageNamesFor(in Input) []string

PipelineStageNamesFor 는 렌더 입력이 실제로 만들 단계 이름이다.

렌더러와 같은 판단(stageOptionsFor)을 쓴다 — 두 곳이 각자 판단하면 선언과 실제가 어긋나고, 어긋나면 화면이 돌지도 않은 단계를 보여준다.

func Render

func Render(in Input) ([]port.CommitFile, error)

Types

type ImportedSource added in v0.6.0

type ImportedSource struct {
	// Origin 은 어디서 무엇을 가져왔는지다. 안내 문서와 빌드 프로필 판단에 쓴다.
	Origin domain.TemplateSource
	// Files 는 그 커밋의 파일이다(port.SourceArchive). 경로는 저장소 루트 기준이다.
	Files []port.CommitFile
}

ImportedSource 는 템플릿이 가져온 원본이다.

type Input

type Input struct {
	AppName string
	// AppType 은 어떤 앱을 만들지다. web 이면 바로 도는 React 앱을 스캐폴딩한다.
	// 비면 예전처럼 자리만 잡는 nginx Dockerfile 을 만든다.
	AppType   domain.AppType
	Namespace string
	Port      int32
	Replicas  int32
	// Platform 은 소스 저장소 플랫폼이다. 비면 GitLab 으로 본다.
	Platform port.SCMPlatform
	// CIPlatform 은 파이프라인 정의를 어느 형식으로 쓸지 정한다.
	//
	// SCM 과 별개의 축이다 — Gitea 는 소스만 담당하고 빌드는 Jenkins 가 한다.
	// 비면 Platform 이 함의하는 기본 CI 를 쓴다.
	CIPlatform port.CIPlatform
	// ImageTarget 은 resolver 가 정한 이미지 저장 위치다.
	ImageTarget *port.ImageTarget
	// AccessDomain / GatewayName / GatewayNamespace 가 모두 있으면
	// 외부 접근용 HTTPRoute 를 함께 만든다. 없으면 클러스터 내부에서만
	// 접근 가능한 Service 까지만 만든다.
	AccessDomain     string
	GatewayName      string
	GatewayNamespace string
	// StackID 는 배포된 워크로드가 어느 스택 소속인지 클러스터에서 알아보게 한다.
	// 네임스페이스로는 판별할 수 없다 — 파이프라인이 default 에 깔 수도 있고
	// 여러 스택이 한 네임스페이스를 공유할 수도 있다. 비면 라벨을 붙이지 않는다.
	StackID string
	// TemplateID 는 어느 CI/CD 템플릿에서 나온 앱인지 알아보게 한다.
	// 템플릿별 자원 사용 비교나 템플릿 단위 조회에 쓴다. 비면 라벨을 붙이지 않는다.
	TemplateID string
	// ImageScannerEndpoint 는 스택 Trivy 서버의 클러스터 내 주소다.
	//
	// 비면 이미지 스캔 단계를 만들지 않는다. 돌지도 않을 단계를 선언하면
	// 화면이 그것을 성공으로 보여준다(마이그레이션 000070).
	ImageScannerEndpoint string
	// ImageScannerJavaDBRepository 는 에어갭 설치에서 CI 잡의 trivy client 가 Java DB 를
	// 받을 내부 미러다. client 는 Maven 메타데이터가 없는 JAR 을 만나면 Java DB 를 스스로
	// 받는데 기본 주소(mirror.gcr.io)는 에어갭에서 닿지 않는다. 비면 업스트림 기본값을 쓴다.
	ImageScannerJavaDBRepository string
	// SASTServerEndpoint 는 스택 SonarQube 의 클러스터 내 주소다.
	//
	// 비면 소스 정적 분석 단계를 만들지 않는다 — 이미지 스캔과 같은 이유다.
	SASTServerEndpoint string
	// DependencyScanEndpoint 는 의존성 스캔(SCA)이 붙을 스택 Trivy 서버 주소다(#79).
	//
	// 비면 의존성 스캔 단계를 만들지 않는다 — 이미지 스캔·SAST 와 같은 이유다.
	DependencyScanEndpoint string
	// Source 는 템플릿이 가져온 원본이다. 있으면 앱 자리(React·자리표시자 Dockerfile·README)를
	// 만들지 않고 원본 파일 위에 플랫폼 소유 파일만 얹는다(imported_source.go).
	Source *ImportedSource
}

Input 은 스캐폴딩 렌더 요청이다.

type StageOptions added in v0.6.0

type StageOptions struct {
	ImageScan bool
	// SAST 는 스택 SonarQube 로 소스를 분석하는 단계다(#64).
	SAST bool
	// SecretScan 은 gitleaks 로 시크릿 유출을 찾는 단계다(#80). 스택 의존이 없어 언제나 켜진다 —
	// 끄는 것은 정책(NULLUS_SECRET_DETECTION=off)이다.
	SecretScan bool
	// DependencyScan 은 락파일로 서드파티 의존성 취약점을 찾는 단계다(#79). 스택에서 의존성 스캔을
	// 골랐을 때만 — 스택 Trivy 서버가 있어야 한다.
	DependencyScan bool
}

StageOptions 는 선택적 단계의 on/off 다.

파이프라인 단위 선택이라 템플릿이 아니라 파이프라인이 들고 있어야 한다. #64(SAST) · #79(SCA) · #80(Secret Detection) 도 여기에 자리를 더한다.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL