History
- CI/CD가 없이 로컬에서 패키지 배포를 해야 하는 상황
- private npm 배포를 위해 CI 토큰을 발급받았다.
Task
- 명령어로 npm publish가 가능해야 한다.
- CI Token은 깃허브 저장소에 올라가면 안된다.
Issue
- 배포할 때마다 CI 토큰을 .npmrc에 넣어서 인증하고 있었다. 혹은 npm cli를 통해
Solution
동작 형태
package.json에 prepost prefix를 이용한 스크립트를 작성한다.
"prepublish": "node ./scripts/prepublish.js",
"publish": "npm publish --registry=https://npm.linecorp.com",
"postpublish": "node ./scripts/postpublish.js"
/* eslint-disable @typescript-eslint/no-var-requires */
const fs = require('fs')
const path = require('path')
const npmrcPath = path.resolve(__dirname, '..', '.npmrc')
const envPath = path.resolve(__dirname, '..', '.env')
function readEnvVariable(variable) {
const envContents = fs.readFileSync(envPath, 'utf8')
const match = envContents.match(new RegExp(`^${variable}=(.*)$`, 'm'))
return match && match[1]
}
function prepublish() {
const token = readEnvVariable('NPM_CI_TOKEN')
if (!token) {
console.error('NPM_CI_TOKEN not found in .env file')
process.exit(1)
}
let npmrcContents = fs.readFileSync(npmrcPath, 'utf8')
npmrcContents += `\n//npm.linecorp.com/:_authToken=${token}`
fs.writeFileSync(npmrcPath, npmrcContents)
}
prepublish()
.env파일의 NPM_CI_TOKEN 값을 받아와서 .npmrc 파일의 authToken에 넣어준다./* eslint-disable @typescript-eslint/no-var-requires */
const fs = require('fs')
const path = require('path')
const npmrcPath = path.resolve(__dirname, '..', '.npmrc')
function postpublish() {
let npmrcContents = fs.readFileSync(npmrcPath, 'utf8')
npmrcContents = npmrcContents.replace(/\n\/\/npm\.linecorp\.com\/:_authToken=.*/, '')
fs.writeFileSync(npmrcPath, npmrcContents)
}
postpublish()
.npmrc는 트래킹이 되고 있는 파일이기 때문에 token이 저장되면 안된다.prepublish.js에서 입력한 라인을 postpublish.js에서 제거해준다.