ãã®è¨äºã¯ããBASE Advent Calendar 2019ãã®3æ¥ç®ã®è¨äºã§ãã
åã®æ¥ã¯ id:ngsw ã®EC2ã«ãããåä½æéãããã®åå解決å¶éã®å¯¾å¿ã¨ id:chiiichellã®ã¨ã³ã¸ãã¢2å¹´çããªã¼ããã«ã³ã¼ããèªãã§ä»å¹´èªåãæ¸ããã³ã¼ããæ¯ãè¿ãã§ããã devblog.thebase.in
Product Dev Divisionã®å è³è°·ã§ããå é¨çµ±å¶ã®å®ç¾æ段ã®1ã¤ã§ãããITã¸ã®å¯¾å¿ãã«ã¤ãã¦æ´åæ¹åãæ¥ã é²ãã¦ãã¾ãã社å ã®å é¨çµ±å¶äºåå±ã¨ç£æ»æ³äººã«è©ä¾¡ã¨ã¢ããã¤ã¹ãããã ããªãããITçµ±å¶ã®ãã¡ã®å ¨è¬çµ±å¶ã¸ã®å¯¾å¿ãå®æ½ãã¦ãã¾ãã
AnyPay社ããã®GitHubãçµç¹éå¶ã«æ´»ç¨ããäºä¾ã«ããã¨ãããæ´»åã®ä¸ã§è¡ãææ¸ç®¡çãæ¿èªã証跡管çã«GitHubãã¨ã¦ãæå¹ã ã¨æãããã¨ãå¤ãããã¾ããããã®è¨äºã§ã¯å ã®è¨äºã«å¦ã³è¡ã£ã¦ããä¸ã§ãå¼ç¤¾ã®ITçµ±å¶ã«ãããGitHubã®æ´»ç¨äºä¾ããç´¹ä»ãããã¨æãã¾ãã
è¦ç¨é¡ã®ç®¡ç
GitHubã«ãªãã¸ããªãä½ããè¦ç¨é¡ãMarkdownã§çµ±å¶é ç®æ¯ã«.mdãã¡ã¤ã«ãä½ã£ã¦ãã¾ããã¢ããã¤ã¹ããã ãããã¨ãGitHub Issueã«èµ·ããã¦è°è«ãé²ããè¦ç¨ã®æ´æ°ã¯ãã«ãªã¯ã¨ã¹ããçµã¦masterã¸ãã¼ã¸ãã¦ãã¾ããGitHub Flowã§éç¨ãã¦ãã¦ãmasterãç¾å¨é©ç¨ããã¦ããçµ±å¶ã®æ´åç¶æ³ã¨ãã¦ãã¾ãã
è¦ç¨é¡ã¯ä¸åº¦ä½ãçµãããçµäºã¨ãããã®ã§ã¯ãªããä¼ç¤¾ããµã¼ãã¹ã®ç¶æã¨çºå±ã®ããã«æ¹åãå ãã¦ãããã®ãªã®ã§ãã©ããã£ãçµç·¯ã§ãã®æ¹æ³ã«ãªã£ãã®ããã©ããªIssueããã©ããªè°è«ããããã®ãã追跡ãæ¤ç´¢ãã§ãããã¨ã大åã§ãããããã£ãé¢ãããGitHubã¯ã¨ã¦ãæå¹ã§ãã
PDFã¨ãã¹ãã£ã³ã°
ã¾ããGitHubã¨ã¯ç´æ¥é¢ä¿ããã¾ããããè¦ç¨é¡ãMarkdownã§æ¸ãã¦ããã¦è¯ãã£ããã¨ãç´¹ä»ãã¾ããGitHubã§Markdownã表示ã§ããã¨ã¯ãã社å¤ã®ç£æ»æ³äººã¨ããã¨ãããæãããã®ã§ããªãã¸ããªã«åå ãã¦ããããã¨ã¯ç¾å®çã«é£ããã£ãããã¾ããããã§ãã¹ã¯ãªããã§MarkdownãPDFã«å¤æãã¦ãã¾ããmarkdown-pdfã§ã¯CSSã§ãã©ã³ããç´ã®ãµã¤ãºãæå®ãããã¨ãã§ããã®ã§ãææ¸ã®ãã¼ã¿ã¨ä½è£ãåãã¦èãããã¨ãã§ãã¾ããconcatãã§ããã®ã§ã1ã¤ã®Markdownãã¡ã¤ã«æ¯ã«1PDFã§ã¯ãªããè¦ç¨é¡ã®ã¾ã¨ã¾ãæ¯ã«1ã¤ã®PDFã«concatãã¦ãã¾ãã
pdf.js
#!/usr/bin/env node const fs = require('fs'), path = require('path'), markdownpdf = require('markdown-pdf'), config = require('config'); const walk = (dir, callback) => { fs.readdirSync(dir).forEach((item) => { const filePath = path.join(dir, item); const stat = fs.statSync(filePath); if (stat.isDirectory()) { walk(filePath, callback); } else if (stat.isFile()) { callback(filePath); } }); }; config.get('pdf.docs').map(doc => { let strings = []; walk(doc.dir, filePath => { if (/.*\.md$/.test(filePath)) { strings.push(fs.readFileSync(filePath, {encoding:'utf-8'}).replace(/---[\s\S]*?---/, '---')); } }); markdownpdf({ paperFormat: "A4", cssPath: "pdf.css", remarkable: { linkify: true, } }) .concat .from.strings(strings) .to(doc.dest, function() { console.log("created", doc.dest); }); });
pdf.css
body { font-size: 0.625em; font-family:"ãã©ã®ãææ ProN W3","Hiragino Mincho ProN","ï¼ï¼³ ï¼°ææ","MS PMincho",serif; } abbr[title]:after, a[href]:after { content: ""; }
GitHubã«åå ãã¦ããªã社å ã¡ã³ãã¼ã«å ¬éããã«ã¯Docusaurusã便å©ã§ããMarkdown+Docusaurusã®æ´»ç¨ã«ã¤ãã¦ã¯BASEã®éçºè æ§åãæ©è½ã®ããã¥ã¡ã³ããµã¤ãããªãã¥ã¼ã¢ã«ããã¨ãã®è¨äºãã覧ä¸ããã
ç¹æ¨©IDã®ç®¡çã¨æ¿èª
æ¬çªãã¼ã¿ãã¼ã¹ãªã©ã®éè¦ãªã·ã¹ãã ã«ã¢ã¯ã»ã¹ããç¹å¥ãªæ¨©éãæã¤ã¡ã³ãã¼ã¯ãæ¥åã«å¿ãã¦ã¢ã¯ã»ã¹ç®¡ç権éä¸è¦§ã«åºã¥ãè¨å®ãã¦ãã¾ããã¾ãç¹æ¨©ã®ä»ä¸ã権éãå¤æ´ããéã«ã¯è²¬ä»»è ã®æ¿èªãå¿ è¦ã¨ããã¯ã¼ã¯ããã¼ã«ãã¦ãã¾ããä»èª°ãã¢ã¯ã»ã¹æ¨©éãæã£ã¦ãããã®ä¸è¦§ãã©ãããçç±ã§ç³è«ããã®ãã誰ãæ¿èªããã®ããã¯ã¼ã¯ããã¼ã®æ§ç¯ã¨è¨¼è·¡ç®¡çãã¢ãã¿ãªã³ã°ã«GitHubã使ã£ã¦ãã¾ãã
ã¢ã¯ã»ã¹ç®¡ç権éä¸è¦§ãYAMLã§æ¸ãã¦ããã追å åã³åé¤ã®ç³è«ã¯YAMLãã¡ã¤ã«ã¸ãã«ãªã¯ã¨ã¹ãããã¦ãå¿
è¦ãªæ¿èªè
ã®ã¬ãã¥ã¼ï¼PullRequestã®approvedï¼ãåããéç¨ã«ãã¦ãã¾ããæ¿èªè
ã¯CODEOWNERS ã«å®ç¾©ãããã¨ã§ãã«ãªã¯ã¨ã¹ãä½ææã«èªåã§åºå®ã§ãã¾ãã.github/CODEOWNERS
ãã¡ã¤ã«èªä½ã®ã³ã¼ããªã¼ãã¼ã¯ãã¢ãã¿ãªã³ã°ããã¡ã³ãã¼ã«ãã¦ãã¾ãã
ã¾ã å®æ½ãã¦ãã¾ããããgitãªãã¸ããªå ã®YAMLãã¡ã¤ã«ã«ãããã¨ã§ããã°ã©ã ã¨ã®è¦ªåæ§ãä¸ãããTerraformãAnsibleãªã©ã¤ã³ãã©æ§æ管çã®ä¸ã«ãçµã¿è¾¼ããã¨ãã§ããã¨æãã¾ãã
CODEOWNERS
# CODEOWNERSã®ä¾ã§ãã # ããã©ã«ã * @violetyk # æ¬çªDBã¸ã¢ã¯ã»ã¹ããã¦ã¼ã¶ã®æ¿èª /permissions/production_db.yml @dmnlk
é害管çå°å¸³
åæã¨ãã¦é害ã¯èµ·ããªãããã«çãè¬ããã®ã§ãããä¸ãä¸äºæ ãé害ãèµ·ããã¨ãã«ã¯è§£æ±ºã«è³ãã¾ã§ãè¨é²ã»ç®¡çããæ段ãè¬ãã¦ãããã¨ãå¿ è¦ã§ãã
é害ã®è¨é²ã管çã«ã¯GitHub IssueããIssueã®èªåä½æã«GitHub Actionã使ã£ã¦ãã¾ããå¼ç¤¾ã§ã¯é害çºçæã®ã¯ã¼ã¯ããã¼ã¨ãã¦ãSlack㧠#incident_yyyymmdd
ã®ãããªãã£ã³ãã«ãä½ãç¾æ³å ±åãããã¨ããããå§ã¾ãã¾ãï¼Slackããã¦ã³ãã¦ããã代æ¿ã®ãã£ããã§ï¼ã
GitHub Actionã§å®æçã«é害ã®ãã£ã³ãã«ãä½ããã¦ãããã©ãããç£è¦ãããã£ãå ´åã«ã¯GitHubã«é害管çIssueãä½ãã¾ããé害管çIssueã¯èªåçã«incident
ã¿ã°ãã¤ãã¦è²¬ä»»è
ã«ã¢ãµã¤ã³ããã¾ãã責任è
ãéå®³å ±åãæ¸ãã¦é害対å¿ãçµãã£ããIssueãã¯ãã¼ãºãã¦ãã¾ãã
GitHubã§ç®¡çã起票ãèªååãããã¨ã§ãå ±åæ¼ãããªãããæªè§£æ±ºã®é害ãæ ¹æ¬å¯¾å¿ãè¦ãããã®ã®å®æçãªæ£å¸ããªã©ã容æã«ãªãã¾ããã
GitHub Action
é害ã®ãã£ã³ãã«ãç£è¦ãã¦Issueãèªåã§ä½ãGitHub Actionã¯æ¬¡ã®ããã«æ¸ãã¦ãã¾ãã
.github/workflows/create_issues.yml
name: Create Github issues from Slack incident channels on: schedule: - cron: '0 1 * * *' jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Set up Python 3.7 uses: actions/setup-python@v1 with: python-version: '3.7' architecture: 'x64' - name: Install dependencies run: | pip install --upgrade pip pipenv pipenv sync - name: Create issues env: SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }} run: | YYYYMMDD=`date +"%Y%m%d" --date "1 day ago"` pipenv run create_issues --repo=baseinc/info-system --term=${YYYYMMDD} --label=incident --assignee=xxxx
JasonEtco/create-an-issue
GitHub Actionã®JasonEtco/create-an-issueã¯Issueããã³ãã¬ã¼ãããä½ãActionã§ãããã®Actionãå®æçã«è¡ãå¿ è¦ãããSaaSã®ã¢ã«ã¦ã³ãã®æ£å¸ãã¿ã¹ã¯ã«ä½¿ã£ã¦ãã¾ããGitHub Issueã¨ãã¦ä½æããåSaaS管çè ã«ã¢ãµã¤ã³ãæ£å¸ãå 容ãæ¸ãã¦çµãã£ããã¯ãã¼ãºããã¨ããéç¨ã§è¨¼è·¡ç®¡çãã¦ãã¾ãã
.github/workflows/create_issues_quarterly.yml
name: Create issues quarterly on: schedule: # 1Q(1/1), 2Q(4/1), 3Q(7/1), 4Q(10/1) (UTC) - cron: '0 1 1 1,4,7,10 *' jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v1 - name: Review Slack uses: JasonEtco/[email protected] with: args: workflow_templates/review_accounts/slack.md
å é¨çµ±å¶ã®ç°å¢æ´åã¨éçºè ä½é¨ã®ä¸¡ç«ãç®æãã¦
å¼ç¤¾ã®äºä¾ããç´¹ä»ããã¦ããã ãã¾ãããã¾ã ã¾ã ææ¢ãã§ãã£ã¦ããã¨ãããå¤ãã®ã§ãæ´»ç¨äºä¾ããæã¡ã®æ¹ããã£ããã£ãããã²ã話ãèããã¦ããã ãããã§ãã ã³ã¼ãã¬ã¼ãã¨ã³ã¸ãã¢ã®ããã·ã§ã³ã¯ãã·ã§ãããªã¼ãã¼ã«å®å¿ãã¦ãµã¼ãã¹ã使ãç¶ãã¦ããã ãããã«ãæ¥åã®æå¹æ§åã³å¹çæ§ã»è²¡åå ±åã®ä¿¡é ¼æ§ã»äºæ¥æ´»åã«é¢ããæ³ä»¤ãªã©ã®éµå®ä¸¦ã³ã«è³ç£ã®ä¿å ¨ã¨ãã£ãå é¨çµ±å¶ã®ç°å¢æ´åã¨éçºè ä½é¨ã®ä¸¡ç«ãèãç¶ããæ¹åãç¶ãã¦ãããã¨ã§ããå¿ è¦ä»¥ä¸ã®ã«ã¼ã«ãéç¨ãé£ããçµ±å¶ãåºãããã¨ã§ãµã¼ãã¹ã®æé·ã¹ãã¼ããè½ã¨ãããéã«å éã§ãããããæè»ãªãã©ã³ã¹æãæã£ã¦æ¹åãé²ãã¦ããããã¨æãã¾ãã
ææ¥ã¯ id:khigashigashi 㨠id:smdksk ã§ããã楽ãã¿ã«ï¼
ãBASE Advent Calendarãã®è¨äºä¸è¦§ã¯ãã¡ãã§ãã devblog.thebase.in