Initial commit
This commit is contained in:
@@ -0,0 +1,392 @@
|
||||
= 로컬 설치
|
||||
|
||||
== Maven 설치
|
||||
|
||||
Apache Maven(https://maven.apache.org/download.cgi )에서 다운 받아 설치한다.
|
||||
OS에 맞는 파일을 다운로드 한다.
|
||||
Windows의 경우 **Binary zip archive**를 추천한다.
|
||||
|
||||
image::maven_01.png[maven_01]
|
||||
|
||||
적당한 위치에 압축을 풀고 시스템 환경변수에서 %MAVEN_HOME%을 추가한다.
|
||||
|
||||
image::maven_02.png[maven_02]jdbc:
|
||||
|
||||
시스템 환경변수 path에 %MAVEN_HOME%\bin을 추가한다.
|
||||
|
||||
image::maven_03.png[maven_03]
|
||||
|
||||
cmd창을 열어 *mvn -version* 명령어를 실행한다.
|
||||
아래처럼 설치된 Maven 버전이 출력되면 된다.
|
||||
|
||||
image::maven_04.png[maven_04]
|
||||
|
||||
IMPORTANT: 사업장 Proxy 세팅을 위해 각 사업장 Proxy 정보를 Users/사용자명/.m2/settings.xml에 아래와 같이 추가한다.
|
||||
(settings.xml 파일이 없을 경우 %MAVEN_HOME%\conf\settings.xml 파일을 해당 위치에 복사한다.)
|
||||
|
||||
----
|
||||
<settings>
|
||||
<proxies>
|
||||
<proxy>
|
||||
<id>proxy-http</id>
|
||||
<active>true</active>
|
||||
<protocol>http</protocol>
|
||||
<host>168.219.61.252</host> // 사업장 Proxy 정보
|
||||
<port>8080</port> // 사업장 Proxy 정보
|
||||
<nonProxyHosts>*.samsung.net|localhost|127.0.0.1</nonProxyHosts>
|
||||
</proxy>
|
||||
<proxy>
|
||||
<id>proxy-https</id>
|
||||
<active>true</active>
|
||||
<protocol>https</protocol>
|
||||
<host>168.219.61.252</host> // 사업장 Proxy 정보
|
||||
<port>8080</port> // 사업장 Proxy 정보
|
||||
<nonProxyHosts >*.samsung.net|localhost|127.0.0.1</nonProxyHosts>
|
||||
</proxy>
|
||||
</proxies>
|
||||
</settings>
|
||||
----
|
||||
|
||||
== IDE 설치
|
||||
개발자 환경에 맞춰 필요한 IDE를 설치한다.
|
||||
Eclipse의 경우 Spring Framework 개발에 필요한 Plugin이 포함된 Spring Tools Suite를 사용해도 된다. Front-end 개발을 위해서 VS Code 등을 추가로 설치 하는 것도 추천한다. 본 메뉴얼에서는 Eclipse나 IntelliJ 등 IDE 설치에 대해서는 다루지 않는다.
|
||||
|
||||
=== Visual Studio Code 설치
|
||||
NOTE: Visual Studio Code 외 다른 IDE를 사용하는 경우 건너뛴다.
|
||||
|
||||
https://code.visualstudio.com/docs/?dv=win 에 접속해서 설치파일 다운로드
|
||||
|
||||
image::front_02_10.png[front_02_10,800,600]
|
||||
|
||||
== Node.js 설치
|
||||
|
||||
링크(https://nodejs.org/en/ )의 페이지에서 사용중인 OS에 맞는 Node.js 설치파일을 다운로드 받아 설치 한다.
|
||||
|
||||
IMPORTANT: 6.0.0 버전 기준 nodejs 버전 20.14.x 이상을 권장하고 있다.
|
||||
|
||||
image::front_01_1.png[front_01_1,800,600]
|
||||
=== 설치 확인
|
||||
Command 창에 node –v(version) 과 npm –v(version)을 입력합니다. 설치하신 node, npm정보가 조회되면 설치가 완료된 것이다.
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
C:\>node -v
|
||||
v20.14.0
|
||||
C:\>npm -v
|
||||
9.0.2
|
||||
----
|
||||
|
||||
=== npm 설정 방법
|
||||
Node library를 다운로드 받지 못하는 경우, NPM 설정이 필요하며, 설정에 필요한 명령어는 npm config set {환경변수명} {값} 이다.
|
||||
현장의 proxy 서버에 맞게 명령어를 구성하면 되며, Proxy 설정 명령어는 아래와 같다.
|
||||
npm 설정방법에 대한 자세한 설명은 https://docs.npmjs.com/misc/config[npm-config]를 참고 바란다.
|
||||
|
||||
image::front_02_3.png[]
|
||||
|
||||
=== npm 설정 확인
|
||||
npm 설정정보를 확인하기 위해 npm config list 명령을 수행한다.
|
||||
아래 그림과 같이 설정한 값이 보이면 NPM 설정 완료.
|
||||
|
||||
image::front_02_4.png[]
|
||||
|
||||
== Eclipse (STS) Setting
|
||||
|
||||
다운받은 sdl-base-[version].zip 파일을 임의의 프로젝트 폴더 아래 압축을 푼다.
|
||||
|
||||
image::install_1.png[]
|
||||
|
||||
Eclipse 실행 후 workspace 설정
|
||||
|
||||
image::install_2.png[install_2,800,600]
|
||||
|
||||
Eclipse 실행 후 완료
|
||||
|
||||
image::install_09.png[install_09,800,600]
|
||||
|
||||
Project Encoding 설정
|
||||
|
||||
image::install_10.png[install_10,450,600]
|
||||
|
||||
Validation Disable All
|
||||
|
||||
image::install_11.png[install_11,450,600]
|
||||
|
||||
Server 설정
|
||||
|
||||
본 문서에서는 로컬 WAS 설치 방법은 다루지 않는다. +
|
||||
SDL은 스프링 부트가 기본 제공되므로 로컬 서버로는 스프링 부트 내장 Tomcat을 사용한다.
|
||||
|
||||
== Eclipse Project Import
|
||||
|
||||
File -> Import -> Maven Project -> Existing Maven Projects
|
||||
|
||||
image::install_16.png[]
|
||||
|
||||
image::install_17.png[]
|
||||
|
||||
sdl-base 프로젝트를 설치한 위치를 선택한다
|
||||
|
||||
image::install_18.png[]
|
||||
|
||||
Import가 완료 되면 Package Explorer에서 아래처럼 프로젝트를 볼 수 있다.
|
||||
|
||||
image::install_19.png[]
|
||||
|
||||
CAUTION: 프로젝트를 처음 Import 할 경우 Build Path에서 Resource폴더가 Excluded 되어 있을 수 있으니 반드시 확인한다.
|
||||
|
||||
Package Explorer에서 오른쪽 마우스 클릭 -> Build Path -> Configuration Build Path...
|
||||
|
||||
image::install_20.png[]
|
||||
|
||||
Source Tap에서 resources, resouces-local의 Excluded 가 None으로 되어 있나 확인한다.
|
||||
|
||||
image::install_21.png[]
|
||||
|
||||
image::install_22.png[]
|
||||
|
||||
Eclipse 프로젝트 Import가 완료되었다.
|
||||
|
||||
CAUTION: .properties의 한글이 깨진다면 아래처럼 인코딩 설정을 변경한다.
|
||||
|
||||
image::install_28.png[]
|
||||
|
||||
== Lombok Plugin 설치
|
||||
|
||||
@Data @Log4j2 와 같은 Annotation에서 Compile 에러가 발생한다면 Lombok 플러그인을 설치한다.
|
||||
|
||||
https://projectlombok.org/download 에서 lombok jar 파일을 다운로드 받는다.
|
||||
|
||||
image::lombok_01.png[lombok_01,500,35]
|
||||
|
||||
java -jar lombok.jar 을 cmd창에서 실행한다.
|
||||
|
||||
image::lombok_02.png[lombok_02,600,450]
|
||||
|
||||
<1> Specify location..클릭
|
||||
<2> Eclipse 설치 위치 선택
|
||||
<3> Install/Update 클릭
|
||||
|
||||
image::lombok_03.png[lombok_03,600,450]
|
||||
|
||||
설치 완료
|
||||
|
||||
== Server 실행
|
||||
|
||||
DB 접속 정보를 프로젝트 환경에 맞게 수정한다. (예. Postgresql 일 경우)
|
||||
|
||||
.config.properties
|
||||
[source, properties]
|
||||
----
|
||||
# Datasource(Postgresql)
|
||||
datasource.driver=ENC(zg2s0lzTKz1OADpB2LmIk7pcJNLonCsW4WerSDJ9WTfmimam1Zi0Z8mH16+mWY+y)
|
||||
datasource.url=ENC(QaTWEyV020nKVDYneWGs8WNrezY8FGOKyleE2pkxlSs8m8nXE2/mqYMSaqAwUJghMJnLp20twDvdHh4csOKDzw==)
|
||||
datasource.username=ENC(Vz2UR99au+VBAaVJBDSdLw==)
|
||||
datasource.password=ENC(Wrer0/kHw+6UyGhtBT+bdSZNo83x+HNB)
|
||||
----
|
||||
IMPORTANT: 해당 정보는 중요 정보로써 암호화를 통해 정보 탈취등의 보안 사고를 대비해야 한다.
|
||||
표준개발라이브러리에서는 Jasypt(Java Simplified Encryption) 방식을 통해 해당 정보를 암호화 하고 있다.
|
||||
|
||||
* 프로퍼티 값 암호화는 아래 링크의 내용을 참고하여 작성 및 입력한다.
|
||||
(암호화가 필요한 정보만 따로 암호화하도록 한다.)
|
||||
+
|
||||
<<_properties_암호화_툴_사용_방법, Properties 암호화 툴 사용 방법>>
|
||||
+
|
||||
|
||||
* 암호화에 사용된 키 값을 시스템 환경변수 또는 JVM 옵션을 사용하여 지정하면
|
||||
서버 구동 시 복호화 되어 DB에 접속 된다.(JasyptConfig.java)
|
||||
** 시스템 환경변수 사용
|
||||
*** Windows
|
||||
+
|
||||
제어판 -> 시스템 -> 시스템 환경 변수 편집 -> 환경 변수 -> 시스템 변수 JASYPT_KEY 추가
|
||||
+
|
||||
----
|
||||
C:\Users\bbnydory>echo %JASYPT_KEY%
|
||||
jfoadjvcoadr0j3402j
|
||||
----
|
||||
+
|
||||
*** Linux
|
||||
+
|
||||
----
|
||||
$ export JASYPT_KEY=jfoadjvcoadr0j3402j
|
||||
----
|
||||
+
|
||||
*** Docker(Guide Jenkins Build)
|
||||
+
|
||||
Docker Container로 어플리케이션을 실행 할 경우 Docker Build 변수를 Dockerfile에 전달해 설정해야 한다.
|
||||
+
|
||||
Jenkins Build Pipeline 환경 변수 설정 부분
|
||||
+
|
||||
----
|
||||
environment {
|
||||
PROJECT_ID = '...'
|
||||
GIT_CREDENTIAL_ID = '...'
|
||||
APP_IMAGE_REPO_CREDENTIAL_ID = '...'
|
||||
CA_CREDENTIAL_ID = '...'
|
||||
IMAGE_REPO = '....'
|
||||
JASYPT_KEY = 'jfoadjvcoadr0j3402j'
|
||||
}
|
||||
----
|
||||
+
|
||||
Jenkins Build Pipeline Doker 이미지 빌드 부분
|
||||
+
|
||||
----
|
||||
docker login -u $APP_IMAGE_REPO_USERNAME -p $APP_IMAGE_REPO_PASSWORD redii.secmis.sdspaas.io
|
||||
docker build --pull --force-rm --file=Dockerfile --build-arg JASYPT_KEY=$JASYPT_KEY --tag=$IMAGE_LOC .
|
||||
----
|
||||
+
|
||||
*--build-arg JASYPT_KEY=$JASYPT_KEY* 옵션으로 환경변수를 Dockerfile에 전달해야 한다.
|
||||
+
|
||||
Dockerfile 환경 변수 설정
|
||||
+
|
||||
----
|
||||
FROM redii.secmis.sdspaas.io/sdspaas-mw/xxxxxx
|
||||
|
||||
ARG JASYPT_KEY
|
||||
ENV JASYPT_KEY $JASYPT_KEY
|
||||
----
|
||||
|
||||
** JVM 옵션 사용
|
||||
+
|
||||
WAS의 실행 명령어 또는 실행시 에 *-DJASYPT_KEY=jfoadjvcoadr0j3402j* 를 추가해서 어플리케이션을 실행한다.
|
||||
+
|
||||
----
|
||||
$ java -server -Xms8g -Xmx8g -XX:MaxMetaspaceSize=256m -Dspring.profiles.active=prod -DJASYPT_KEY=jfoadjvcoadr0j3402j
|
||||
----
|
||||
|
||||
NOTE: Properties 암호화 툴에서 사용한 키 값(jasypt.key파일내용)과 Jasypt 암호화 키(JASYPT_KEY) 값은 일치해야 한다. +
|
||||
환경변수와 key 값, value은 시스템 내에서 자유롭게 설정하도록 한다. +
|
||||
위의 value값은 절대로 샘플의 값을 사용하지 않도록 한다.
|
||||
|
||||
.SpringConfig.java
|
||||
[source, java]
|
||||
----
|
||||
@Bean
|
||||
public SqlSessionFactoryBean defaultSqlSessionFactory(DataSource dataSource,
|
||||
ApplicationContext applicationContext) throws IOException {
|
||||
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
|
||||
factoryBean.setDataSource(dataSource);
|
||||
factoryBean.setConfigLocation(applicationContext.getResource("classpath:sql/mybatis/postgresql/mybatis-config.xml"));
|
||||
factoryBean.setMapperLocations(applicationContext.getResources("classpath*:sql/mybatis/postgresql/**/mapper-mybatis-*.xml"));
|
||||
return factoryBean;
|
||||
}
|
||||
----
|
||||
|
||||
pom.xml에서 프로젝트에서 사용할 DB의 jdbc driver dependency를 확인/설정한다.
|
||||
|
||||
.pom.xml
|
||||
[source, xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.7.3</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
<artifactId>checker-qual</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
== Spring Boot 실행
|
||||
SDL 6.0은 Spring Boot로 되어 있기 때문에 별도의 WAS 없이 Embedded Tomcat를 이용해 서버를 실행 할 수 있다.
|
||||
|
||||
=== CMD 에서의 실행
|
||||
[source,bash]
|
||||
----
|
||||
mvn spring-boot:run
|
||||
----
|
||||
|
||||
=== IntelliJ 에서 실행
|
||||
프로젝트 창에서 com.samsung.SdlBaseBootApplication.java 파일 선택 후 Spring Boot Application 실행을 한다.
|
||||
|
||||
=== Eclipse 에서 실행
|
||||
Spring Boot로 실행 할 com.samsung.SdlBaseBootApplication.java 파일 선택 후 Spring Boot Application을 실행 한다.
|
||||
|
||||
== VS Code Setting
|
||||
NOTE: Visual Studio Code 외 다른 IDE를 사용하는 경우 건너뛴다.
|
||||
|
||||
Open source
|
||||
File > Open Folder > '\sdl-base\frontend' 선택
|
||||
|
||||
image::front_02_11.png[]
|
||||
|
||||
image::vscode_02.png[]
|
||||
|
||||
VS Code Plugin 설치
|
||||
코딩 컨벤션을 위한 Plugin 설치 - vscode 실행 후 좌측 아이콘 메뉴중 5번째 선택 후 검색어 입력
|
||||
|
||||
"eslint"
|
||||
|
||||
image::front_02_12.png[]
|
||||
"prettier"
|
||||
|
||||
image::front_02_13.png[]
|
||||
|
||||
설치후 vscode 활성화 (저장시 자동 수정)
|
||||
File > Preferences > Settings 메뉴 진입 하거나
|
||||
단축키 Ctrl + Shift + P 를 눌러 아래 검색어 user 입력
|
||||
|
||||
image::front_02_14.png[]
|
||||
설정검색란에 save 입력 후 settings.json에서 편집 클릭
|
||||
|
||||
image::front_02_15.png[]
|
||||
JSON 파일에 아래 코드 추가
|
||||
|
||||
image::front_02_16.png[]
|
||||
|
||||
CAUTION: vscode 에서 eslint가 너무 늦게 적용될때 환경변수에 NO_UPDATE_NOTIFIER=1 추가하면 됨
|
||||
(참고링크 https://github.com/Microsoft/vscode-eslint/issues/440#issuecomment-380083518 )
|
||||
|
||||
image::front_02_17.png[]
|
||||
|
||||
== Frontend 설치 및 실행
|
||||
[[npm-install]]
|
||||
Frontend 실행에 필요한 node module 설치
|
||||
|
||||
IDE에서 Terminal을 생성하여 npm install 명령어를 실행
|
||||
|
||||
.npm-install
|
||||
[source,shell]
|
||||
----
|
||||
C:\~YOUR~PROJECT~PATH~\sdl-base\frontend>npm install
|
||||
----
|
||||
|
||||
Vite dev-server 의 경우 host: 'localhost', port: 5173 이 default 값으로 설정되어있다.
|
||||
|
||||
SDL 은 dev-server 의 port 값을 '8081'로 사용하고 있으며, frontend/vite.config.js 파일에서 아래와 같이 서버 설정
|
||||
을 확인 및 수정 할 수 있다.
|
||||
|
||||
.vite.config.js
|
||||
[source, json]
|
||||
----
|
||||
server: {
|
||||
// host: 'localhost' // default
|
||||
port: '8081',
|
||||
}
|
||||
----
|
||||
|
||||
로컬 환경 설정 파일 .env.test 파일을 열어 Back-end 정보를 입력한다.
|
||||
|
||||
..env.test
|
||||
[source, properties]
|
||||
----
|
||||
VITE_NODE_ENV=local
|
||||
VITE_API_URL=http://localhost:8080
|
||||
VITE_DIST_PATH=../src/main/resources/public
|
||||
VITE_WEB_CONTEXT_PATH=/
|
||||
----
|
||||
|
||||
npm run local 명령어를 통해
|
||||
local 환경에서의 vite dev-server를 실행한다
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
C:\~YOUR~PROJECT~PATH~\sdl-base\frontend>npm run local
|
||||
----
|
||||
|
||||
== Local 접속 확인
|
||||
Web browser(Chrome, Edge)에 http://localhost:8081 입력 후 실행
|
||||
|
||||
image::front_02_20.png[front_02_20,450,600]
|
||||
@@ -0,0 +1,130 @@
|
||||
= 빌드&배포
|
||||
|
||||
== Vite Bundling
|
||||
SDL6 UI는 서비스 하기 위해 Bundling이 필요하다.
|
||||
각 배포 대상에 따른 설정 파일은 .env.test , .env.development, .env.production 파일을 참고한다.
|
||||
|
||||
..env.production 예시
|
||||
[source, properties]
|
||||
----
|
||||
# default env
|
||||
VITE_NODE_ENV=production
|
||||
VITE_API_URL=http://sdl.sec.samsung.net/administrator
|
||||
VITE_DIST_PATH=../src/main/webapp/pp
|
||||
# CONTEXT_PATH value must be end with '/'
|
||||
VITE_WEB_CONTEXT_PATH=/
|
||||
----
|
||||
|
||||
package.json 에 정의된 script에 따라 설정 파일이 적용된다.
|
||||
|
||||
.package.json
|
||||
[source, json]
|
||||
----
|
||||
"scripts": {
|
||||
"local": "vite --mode test",
|
||||
"dev": "vite --mode development",
|
||||
"prod": "vite --mode production",
|
||||
"build": "vite build --mode production",
|
||||
"build-test": "vite build --mode test",
|
||||
"build-dev": "vite build --mode development",
|
||||
"build-prod": "vite build --mode production",
|
||||
"preview": "vite preview --mode production",
|
||||
"preview-test": "vite preview --mode test",
|
||||
"preview-dev": "vite preview --mode development",
|
||||
"preview-prod": "vite preview --mode production",
|
||||
"lint": "eslint src/**/*.{vue,js}"
|
||||
},
|
||||
----
|
||||
|
||||
*npm run local* 명령어를 실행할 경우 .env.test 파일이 적용되며, vite-dev-server가 실행된다.
|
||||
vite-dev-server는 front-end 코드가 실시간으로 반영되므로 개발 시 편리하다.
|
||||
|
||||
*npm run preview* 명령어를 통해 빌드 된 결과물을 preview 서버를 통해 확인 할 수 있다.
|
||||
반드시 *VITE_DIST_PATH* 에 Build 결과물이 존재해야 구동된다.
|
||||
|
||||
== SonarQube Scanner 를 통한 소스코드 정적 분석
|
||||
|
||||
* 먼저 SonarQube Scanner 를 설치한다.
|
||||
|
||||
----
|
||||
npm install sonar-scanner -g
|
||||
----
|
||||
|
||||
* 사용법 (Command Line)
|
||||
|
||||
----
|
||||
cd sdl-base <1>
|
||||
|
||||
sonar-scanner -Dsonar.host.url=SonarQube서버URL -Dsonar.projectKey=프로젝트Key -Dsonar.projectName=프로젝트명 -Dsonar.projectVersion=프로젝트버전 -Dsonar.login=아이디 -Dsonar.password=패스워드 -Dsonar.sources=frontend/src <2>
|
||||
----
|
||||
|
||||
<1> 분석하고자 하는 프로젝트로 이동한다.
|
||||
<2> 설정한 파라미터값으로 실행한다.
|
||||
|
||||
.파라미터 설명
|
||||
[width="100%",options="header"]
|
||||
|=====
|
||||
| key | value(예) | 설명 | 비고
|
||||
|
||||
| sonar.host.url
|
||||
| \http://guide.sonarqube.sec.samsung.net
|
||||
| SonarQube 서버 URL
|
||||
| 필수
|
||||
|
||||
| sonar.projectKey
|
||||
| my:project
|
||||
| 분석하고자 하는 프로젝트의 고유한 키 값
|
||||
| 필수
|
||||
|
||||
| sonar.projectName
|
||||
| "my project for test"
|
||||
| 프로젝트 이름
|
||||
|
|
||||
|
||||
| sonar.projectVersion
|
||||
| 1.0
|
||||
| 프로젝트 버전
|
||||
|
|
||||
|
||||
| sonar.login
|
||||
| user01
|
||||
| SonarQube 서버 로그인 ID
|
||||
| 필수
|
||||
|
||||
| sonar.password
|
||||
| passwd01
|
||||
| SonarQube 서버 로그인 패스워드
|
||||
| 필수
|
||||
|
||||
| sonar.sources
|
||||
| frontend/src
|
||||
| 소스파일이 위치한 디렉토리
|
||||
|
|
||||
|=====
|
||||
|
||||
NOTE: sonar-scanner 파라미터 관련 자세한 내용은 https://docs.sonarqube.org/latest/analysis/analysis-parameters/[공식문서^]를 참조한다.
|
||||
|
||||
== Front-end 빌드
|
||||
|
||||
운영시스템에 배포 하기 위해서 cmd창에서 *npm run-script build* 명령어를 실행한다.
|
||||
빌드 결과는 .env 파일의 *VITE_DIST_PATH* 경로에 생성된다.
|
||||
|
||||
image::build_01.png[build_01,800,600]
|
||||
|
||||
image::build_02.png[]
|
||||
|
||||
== Back-end 빌드
|
||||
|
||||
Back-end는 Maven을 이용해 Build 하고 있다. maven 명령어를 이용해 빌드한다.
|
||||
패키징 시 배포 대상별로 Profile을 적용 할 수 있다.
|
||||
----
|
||||
mvn clean package -Pprod
|
||||
----
|
||||
-Pprod 옵션을 경우 src/main/resource-prod 아래의 설정파일들이 적용되어 패키징 된다.
|
||||
|
||||
image::build_03.png[build_03,800,600]
|
||||
|
||||
IMPORTANT: SDL 6.0은 Spring Profile이 적용되어 서버 실행시 -Dspring.profiles.active=local과 같은 옵션을 필요로 한다.
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
= 설치
|
||||
|
||||
include::로컬설치.adoc[leveloffset=+1]
|
||||
|
||||
include::빌드&배포.adoc[leveloffset=+1]
|
||||
Reference in New Issue
Block a user