VSCode Remote Containersã«èªåã®dotfilesãæã¡è¾¼ã
ã¤ãã«armçã®macOSãçºè¡¨ããã¦ãã¾ã£ãã®ã§ãèªåã¯ãããæ©ã«éçºæ©ãmacããä¹ãæãããã¨èãã¦ãã¾ãããã®ããã«æ³¨ç®ãã¦ããã®ãVSCode Remote Containerã§ãã
Remote Containersã§ä½¿ãã³ã³ããç°å¢ã¯.devcontainerã¨ãããã¡ã¤ã«ã«å®ç¾©ãã¾ãããã©ã¦ã¶ããã§ã使ããã¨ãã§ããVSCode Codespaceï¼VSCode Onlineãããªãã¼ã ãããï¼ããä»å¹´ã«çºè¡¨ãããGitHub Codespaceã§ãåãããã«å®è¡ç°å¢ã.devcontainerã§è¨å®ã§ããããã§ãã
- Developing inside a Container
- Configure Codespace Environments
- Configuring Codespaces for your project
ãããç¥ãã¾ã§ã¯macããWindowsã®WSL2ç°å¢ã«ç§»è¡ããããã¨èãã¦ããã®ã§ãããã³ã³ããã§ããã°ç·©ããã«ç§»è¡ã§ããããVSCodeãã¼ã¹ã®ãªã³ã©ã¤ã³ã¨ãã£ã¿ã§ãåãç°å¢ãåç¾ã§ãããã¨ããWSL2ã«ç§»è¡ãããããçãè¯ãããã«æãã¾ããã
Remote Containersã使ã£ã¦ã¿ã
ã¾ãã¯ããã¥ã¡ã³ããè¦ãªããã試ãã§å§ãã¦ã¿ã¾ããæé èªä½ã¯å ¬å¼ããã¥ã¡ã³ãã«ã¹ã¯ã·ã§ä»ãã§ä¸å¯§ãªè§£èª¬ãããã®ã§ãã¡ããè¦ã¦ãã ãããã½ã¡ã½ã¡é²ããã ãã§VSCodeã.devcontainerãDockerfileã¾ã§çæãã¦ãããã®ã§ã¤ãããææ¸ãã§ç¨æãã¦ããå¿ è¦ã¯ããã¾ããã§ããã
æåã®ã³ã³ããããã«ãããã¨ããã§æéãå°ã ãããã¾ãããããããçµããã°ãã¨ã¯æ®æ®µã®ç°å¢ã¨éè²ãªãã§ããããã¿ã¼ããã«ãéãã°è¦æ £ããLinuxã®ç°å¢ã§ãã
æå®ããã³ã³ããã®ä¸ã§ä½æ¥ããã¦ãããããè¨èªã®ãã¼ã¸ã§ã³ãå½ç¶ã³ã³ããã§ã»ããã¢ããæ¸ã¿ã®ãã®ã使ãã¾ããââenvã¿ãããªãã¼ã¸ã§ã³ãåãæ¿ãããã¼ã«ã¯ä¸è¦ã§ããããã«ããããªãæè¡ã«ãããã®ãVSCodeä¸ã§æä½ããgitã ãã§ã¯ãªããã¿ã¼ããã«ä¸ã§ãèªåã®gitã®è¨å®ãèªè¨¼æ å ±ãå¼ãç¶ããã¦ãã¾ããã³ããããããã°ã¡ããã¨authorã¯èªåã«ãªãã¾ããããã®ã¾ã¾GitHubã«pushãã§ãã¾ãã
ä¸è¦ããã¨ãã¼ã«ã«ç°å¢ã¨æ¯ã¹ã¦ãä½ä¸èªç±ãªãç¶æ
ãªã®ã§ãããæ®æ®µã©ããã«ã¿ã¼ããã«ã使ããã¨ããã¨ä¸ä¾¿ãã«æ°ãä»ãã¾ããls -l
ã®ã¨ã¤ãªã¢ã¹ã¨ãã¦ãã使ãããll
ã使ãã¾ãããå½ç¶la
ãç¡ãããããããlsã®çµæã«è²ãã¤ãã¦ããªããããã«ããã³ãããèªåã®ãæ°ã«å
¥ãã®è¡¨ç¤ºã§ã¯ããã¾ãããããã§ã¯æ®æ®µä½¿ãã«ã¯å³ããã
ï¼æ¬é¡ï¼èªåã®dotfilesãRemote Containersã«æã¡è¾¼ã
MSããã¯ãã®ããããåãã£ã¦ããã®ã§ãèªåã®dotfilesãã³ã³ããã®ä¸ã«æã¡è¾¼ãæ¹æ³ãVSCodeã«ç¨æãã¦ããã¦ãã¾ããæµç³ã§ããã
Personalizing with dotfile repositories
å ¬å¼ããã¥ã¡ã³ãã§ã¯ãã®ããããªã®ã§ãããä¸èº«ãå°ãªãã¦æå¤ã«ããããã¤ã³ããå¤ãã£ãã®ã§è§£èª¬ãã¦ããããã¨æãã¾ãã
ã¾ãã¯ãRemote-Containers: Settingsããå¼ã³åºãã¦è¨å®ç»é¢ã«è¡ãã¾ããè¨å®ããé ç®ã3ã¤åå¨ãããããã以ä¸ã®ãããªæå³ã§ãã
- Dotfiles: Install Command
- git cloneããå¾ã«å®è¡ããã¹ã¯ãªãã
- Dotfiles: Repository
- git cloneããdotfilesã®ãªãã¸ããªãowner/repositoryã®æ¸ãæ¹ã§OK
- Dotfiles: Target Path
- git cloneããå ã®ãã¹
- Remote Containersã®åæã»ããã¢ããæã«é¸æããã³ã³ããã®å ´åãããããrootã¦ã¼ã¶ã¼ã§èµ·åããã®ã§~/dotfilesã®å®éã®ãã¹ã¯/root/dotfilesã¨ãªã
èªåã®dotfilesã®ãªãã¸ããªã«ã»ããã¢ããç¨ã®install.shãç¨æãã¦ãããããããæãã«è¨å®ãã¾ãã
install.shã«ã»ããã¢ããå¦çãæ¸ãã¦ããã¾ããæä½éãæ®æ®µä½¿ããã¦ããaliasã®è¿½å ã¨lsã«è²ã ãã¯ä»ãã¦æ¬²ããã®ã§ãã®ãããªè¨å®ãæ¸ãã¦ã¿ã¾ãã
#!/bin/bash # alias alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' # ls export LS_OPTIONS='--color=auto' alias ls='ls $LS_OPTIONS' alias ll='ls $LS_OPTIONS -hlrt' alias la='ls $LS_OPTIONS -hlrta' export CLICOLOR=1
ãããpushãããå®éã«dotfilesãèªã¿è¾¼ãã§ãããããã«ã³ã³ãããä½ãç´ãã¾ããVSCodeã®å·¦ä¸ã®ç·ã®ãã¿ã³ãæ¼ãã¦ãRemote-Containers: Rebuild Containerããå®è¡ããã¨ã³ã³ãããä½ãç´ãã¦dotfilesãèªã¿è¾¼ã¿ç´ãã¦ããã¾ãã
ãã¦ãèªã¿è¾¼ã¿ãçµãã£ãã®ã§ããã§è§£æ±ºã»ã»ã»ã¨æããããaliasãlsã®è²ä»ããåæ ããã¦ãã¾ãããããã¥ã¡ã³ãã«ãé£ãããã¨ã¯æ¸ãã¦ããªãã£ãã®ã«ãªãï¼
Remote Containersã¨dotfilesã®ã»ããã¢ããã®ä»çµã¿
ä¸æãã§ããªãã£ãçç±ãèãã¾ãããããããã®Remote Containersãã©ãããæé ã§èµ·åãã¦ããã®ããæ¨æ¸¬ãã¦ã¿ã¾ããã
- .devcontainerã«å¾ã£ã¦Dockerfileããã³ã³ããããã«ã
- .devcontainerã«æ¸ããã¦ããextensionsãã¤ã³ã¹ãã¼ã«
docker run âmount type=bind,src=$(pwd),dst=/workspace/{REPO_NAME} {CONTAINER}
ã«è¿ãã³ãã³ãã§VSCodeããéãã¦ãããã£ã¬ã¯ããªã丸ãã¨ã³ã³ããã«mountãã¦å®è¡- dotfilesãgit clone
- æå®ããã¹ã¯ãªãããå®è¡ï¼install.shï¼
- ã³ã³ããå ã§ã·ã§ã«ãèµ·å
- debianç³»ã®ã³ã³ããã ã¨/root/.profileãåå¨ããã®ã§ãããã·ã§ã«èµ·åæã«å®è¡ããã
- .profileã®æå¾ã§.bashrcãèªã¿è¾¼ãï¼
. ~/.bashrc
)
ãã°ãåºã¦ããããã§ã¯ãªãã®ã§èªåã®æ¨æ¸¬ã¨è¦³æ¸¬ããçµæã§ãããããããããããæé ã§å®è¡ããã¦ãã¾ããæå¾ã®.profileã.barshrcã .
ï¼sourceï¼ã§èªã¿è¾¼ã ã®ã«å¯¾ãã¦ã5ã®install.sh㯠æ®éã®ã¹ã¯ãªããã¨ãã¦å®è¡ ããã¾ãã
install.shã«æ¸ããaliasãåæ ããã¦ããªãã®ã¯ãããåå ã§ããæ®éã®ã¹ã¯ãªããã®å®è¡ã¨.
ï¼sourceï¼ã®éãã«ã¤ãã¦ã¯ãã®ãããã®è¨äºãåç
§ãã¦ãã ããã
https://www.atmarkit.co.jp/ait/articles/1712/21/news015.html
install.shã§è¡ãã¹ããã¨
8ã«ããããã«ã³ã³ããã®èµ·åæã«.profileâ.bashrcã®é åºã§èªã¿è¾¼ã¾ãã¦ãããã¨ã¯åãã£ã¦ãã¾ããã¨ãããã¨ã¯ããã¨ãã¨åå¨ãã.bashrcãã·ã³ããªãã¯ãªã³ã¯ã§ç½®ãæãããã¨ã«ããèªåã®.bashrcãèªã¿è¾¼ã¾ãããã¨ãå¯è½ã§ãã
#!/bin/bash cd ~/ ln -fs ~/dotfiles/.bashrc .
å ç¨ã®aliasãªã©ã¯èªåã®.bashrcã«ç§»ããinstall.shã§ã¯ã·ã³ããªãã¯ãªã³ã¯ãè²¼ãã ãã«ãã¾ãããããå度pushããåã³Rebuild Containerãå®è¡ãã¾ãããã
ã§ãã¾ããï¼èªåã¯aliasã¨lsã®è²ä»ãã«å ãã¦ããã³ããã«gitã®ãã©ã³ãã表示ãããããã«å¤æ´ãã¦ã¿ã¾ããããã³ã³ããã®èµ·åæã«èªåçã«åæ ããã¦ãã¾ãã
ããã§ãã¡ã¤ã«æä½ãã¿ã¼ããã«ã§è¡ã硬派ãªã¦ã¼ã¶ã¼ã§ãå¿ç½®ããªãRemote Containersç°å¢ã§ã³ã¼ãã£ã³ã°ã§ããããã«ãªãã¾ãããå¾ã¯ã¿ãªããåèªã§æå¼·ã®dotfilesãç¨æãã¦ãã ããã
æå¾ã«ç¾æç¹ã§ã®èªåã®dotfilesãè²¼ã£ã¦ããã¾ããèªåã®å ´åã¯install_vscode_container.shã¨ããååã«ããã®ã§ãã¡ããåç §ãã¦ãã ããã
èªåã¯aliasã¨lsã®è²ä»ãã«å ãã¦ãããã³ããã«gitã®ãã©ã³ãåã表示ããããgitã®diffãæ¹è¯ããdiff-highlightã使ããããã«ãã¦ãã¾ãã
ãã¾ã install.shã®å¹ççãªãããã°æ¹æ³
install.shãä¿®æ£ãããã³ã«git push
ãã¦VSCodeããRebuild Containerããã®ã¯æéããããã®ã§ããããã°ã¯ãã£ã¨å¹ççãªæ¹æ³ã§è¡ãã¾ãããã
dotfilesã®ãªãã¸ããªãç½®ãã¦ãããã£ã¬ã¯ããªä¸ã§ãã®docker run
ãå®è¡ãã¦ãã ãããdotfilesããã®ã¾ã¾ã³ã³ããå
ã®/home/dotfilesã®ä½ç½®ã«ãã¦ã³ãããç¶æ
ã§bashãèµ·åãã¾ãã使ãã³ã³ããã¯.devcontainersã¨Dockerfileã§èªåã使ãããã³ã³ããã®ååã«å¤æ´ãã¦ãã ããã
docker run --entrypoint=bash --rm -it --mount type=bind,src=$(pwd),dst=/home/dotfiles mcr.microsoft.com/vscode/devcontainers/typescript-node:0-12
ã³ã³ããã®bashãèµ·åãããã³ã³ããã®ä¸ã§install.shãå®è¡ããç¶ãã¦. ~/.profile
ãå®è¡ãããã¨ã§VSCodeã®Remote Containersèµ·åæé ã模å£ã§ãã¾ããdotfilesã¯ãã¹ãå´ã®ãã£ã¬ã¯ããªããã¦ã³ããã¦ããã®ã§ããã¹ãå´ã§ç·¨éããã°ã³ã³ããå
ã«ãå³åæ ããã¾ããæã¿ã®ç¶æ
ã«ãªãã¾ã§å種ãã¡ã¤ã«ãç·¨éããªããèªã¿è¾¼ã¿ç´ãã¦ãããã°ãã¦ããã¾ãããã
ãããã¾ã£ãããªç¶æ
ããããç´ããããªã£ãã¨ãã¯ä¸åº¦ã³ã³ããããæãã¾ããârm
ãªãã·ã§ã³ãä»ãã¦ããã®ã§ãåã³docker run
ããã¨ã¾ã£ãããªç¶æ
ã«æ»ã£ã¦ãã¾ããæçµç¢ºèªã¨ãã¦ã¾ã£ãããªç¶æ
ããå
¨ã¦ãæ£ããè¨å®ã§ãã¦ããã確èªããã¨ããã§ãããã
ç¶ç¶çããªããªã¼ã2020å¹´ã«èªäºããææ³

- ä½è :ï¼ªï½ ï½ ï¼¨ï½ï½ï½ï½ï½ ,Dï½ï½ï½ï½ Fï½ï½ï½ï½ ï½,åæº å³æ¡,é«æ¨ æ£å¼
- çºå£²æ¥: 2017/08/09
- ã¡ãã£ã¢: Kindleç
æ¥åã§å¤§è¦æ¨¡ãªCI/CDãã¤ãã©ã¤ã³ãæ§ç¯ãããã¨ã«ãªã£ãã®ã§ãè¯æ¸ã¨ãã話ãããè³ã«ãã¦ããç¶ç¶çããªããªã¼ãè³¼å ¥ãã¦èªäºãã¾ããã
æ®æ®µã¯æ¸ç±ãèªãã§ãã¡ã¢ãæ®ããã¨ã¾ã§ã¯ã»ã¨ãã©ããªãã®ã§ããããã®æ¬ã¯ãã¤ã¦ç¡ãã»ã©å¾ããã®ãå¤ãã£ãã®ã§èªåã«ãã¦ã¯çããã¡ã¢ãåãã¾ããã
èªåã¨åãããã«å¤§è¦æ¨¡ãªãã¤ãã©ã¤ã³ãè¨è¨ãããã¨ã«è¿«ããã人ã¯ä¸ã«ããã»ã©å¤ããªãã§ãããããããã£ãããªã®ã§å
¬éãããã¨æãã¾ãã
å ¨ä½ã¾ã¨ã
ãã®æ¬ã®æ§æã¯1ç« ã§éè¦ãªãã¨ãã»ã¼å ¨ã¦è¿°ã¹ã¦ããã¨ã®ç« ã§ããããããã«è©³ãã解説ãã¦ãããåããã¨ãå¾ã®ç« ã§ä½åº¦ãç¹°ãè¿ãã®ã§ãã¾ãã«ã大äºãªãã¨ãªã®ã§Nåè¨ãã¾ããããä½ç¾ãã¦ããã ããããããã§ãã®æ¬ã¯1ç« ã«ä¾¡å¤ãè©°ã¾ã£ã¦ãããè¨ãæããã¨ã2ç« ä»¥éã¯èªã¾ãªãã¦ãä½ã¨ããªãããã¼ã¸æ°ãé常ã«å¤ãã®ã§ãèªåãç¹ã«æ°ã«ãªã£ãäºæã®ç« ããèªãã§ããã°è¯ãã
ãã®æ¬ã®åèãæ¸ãããã®ã¯2010å¹´é ã§ãããç´¹ä»ããã¦ãããã¼ã«ã¯2020å¹´ç¾å¨ã®ä»ã§ã¯ååãèããªããªã£ã¦ãã¾ã£ããã®ãå¤ããæ代ã¨ãã¦ã¯ã¯ã©ã¦ãã¯AWSãæµè¡ãå§ããã°ããããã¼ã¸ã§ã³ç®¡çã¯Gitããã¾ã Subversionã®æ¹ã主æµãVMã¯ä½¿ããã¦ãããVagrantãã¾ã ç»å ´ãã¦ãããå½ç¶dockerãåå¨ããªããæ§æ管çã®OSSã¯Puppetã主æµã®æ代ã§ãCI/CDãããã¼ã¸ããµã¼ãã¹ã¯ã¾ã ã»ã¨ãã©ç»å ´ãã¦ãããCluserControlãJenkinsã主æµã®æ代ï¼ç´°ããã¨ããã¯å¾®å¦ã«éããããããªãï¼ã
ããã«ãé¢ãããããã®æ¬ã§ç´¹ä»ããã¦ãããã¨ã®å¤ãã¯10å¹´çµã£ã2020å¹´ã«ããã¦ãé常ã«æç¨ã ã¨æãããã®ãå¤ãã£ããå½æã¯é£ããã£ãããããã¯é«ä¾¡ã ã£ãæ¹æ³ã2020å¹´ç¾å¨ã§ã¯ã¯ã©ã¦ããOSSã®çºå±ã«ãã誰ã§ãç°¡åãã¤å®ä¾¡ã«å®ç¾ã§ããããã«ãªã£ããã®ãå¤ãã10å¹´ãåã«ããããæ¢ã«å®ç¨åããã¦ãã人ãã¡ããããã¨ã«ã¯é常ã«é©ããã
èªåãèªã¿é²ãã¦ãã¦éä¸ããæããã®ã¯ããã®æ¬ã§ç´¹ä»ãã¦ãã大è¦æ¨¡ãªãã¤ãã©ã¤ã³ã«ããã¦éè¦ãªããã¤ãã®ãã¨ã¯2020å¹´ç¾å¨ã§ãæ®å¿µãªããå¤ãã®CI/CDãµã¼ãã¹ã§ã¯ãµãã¼ãããã¦ããªããã¨ã
ã¸ã§ãæ å ±ã®å¯è¦åããããã¤ã¯ãã«ãæ¸ã¿ã®ãã¤ããªã使ããgated checkinããã¤ãã©ã¤ã³ã®æ¿èªããã¼ãªã©ãèªåã®ç¥ãéãããããã®æ©è½ãå ¨ã¦ãã«ã»ããã§æä¾ãã¦ããã®ã¯Azure Pipelineãé¤ãã¦ä»ã«ã¯ãªããAzure Pipelinesã¯ãã¾ãæµè¡ã£ã¦ããå°è±¡ããªãããå®ã¯å¤§è¦æ¨¡ãªãã¤ãã©ã¤ã³ã«ããã¦å¿ è¦ãªãã®ãå ¨æ¹ä½ã§ã«ãã¼ãã¦ããããããµã¼ãã¹ã ã¨ãããã¨ãæ¹ãã¦çºè¦ããã
å°è±¡çã ã£ãé ç®
èªåãèªãã§ãã¦å°è±¡çã ã£ãé ç®ã®ã¡ã¢ãæ®ããããããã«ã¤ãã¦ç´°ãã解説ã¯ããªãã®ã§ãåºæ¬çã«ãã®æ¬ãèªãã ãã¨ããã人 or æå ã«ãã人ãåæã¨ãã¦ãã¾ãã
ãããèªåã®ã³ã¡ã³ãã§å 容ãæ°ã«ãªã£ã人ããããããã²è³¼å ¥ãã¦ã»ãããç¸å½ã®ãã¼ã¸æ°ã§ååãæ¬ãªã®ã§ãå人çã«ã¯é»åæ¸ç±çãè³¼å ¥ãããã¨ããªã¹ã¹ã¡ããã
5.3.1 ãã¤ããªããã«ãããã®ã¯1åéãã¨ãã
åãã½ã¼ã¹ã³ã¼ããå度ãã«ããã¦ä½ããããã¤ããªã¯åºæ¬çã«åä¸ã«ãªããï¼ããã§ãªããã°ãªããªãï¼ããããã¤ã®ããã«å度ã³ã³ãã¤ã«ããã®ã¯æéããããããããã¯å³å¯ã«ã¯åãå ¥ããã¹ããéã£ããã¤ããªã¨ã¯ç°ãªãã®ã§ç°ç©ãç´ãè¾¼ããªã¹ã¯ãåãã¦ããã
ãã¤ããªã¯ã³ãããã¹ãã¼ã¸ã§ãã«ãããããã®ãä¿åãã¦ãããåå©ç¨ããã°ããã
ä»æ¥ã®CI/CDã§ãããéæã§ãã¦ããç¾å ´ã¯ã©ããããããã ãããï¼ãããããã«ãâèªåãã¹ãã¾ã§ããããã10åç¨åº¦ã®å°è¦æ¨¡ãªãã¤ãã©ã¤ã³ã§ããã°ãpull-reqã¨masterã«pushãããã¨ãã®èªåãªãªã¼ã¹ããã¤ãã©ã¤ã³ã¯ã»ã¨ãã©ãå ±éã§ãæå¾ã«ãªãªã¼ã¹ããããããªããã®éããããªããã¨ãå¤ãã¨æãã
ãããããç¾ä»£ã®CIãµã¼ãã¹ã§åã«ãã«ãããææç©ãå¥ã®ãã¤ãã©ã¤ã³ã§åãåºãã¦ä½¿ãã¨ããå·¥ç¨ããµãã¼ããã¦ãããã®ã¯ã»ã¨ãã©ç¡ãæ°ãããããããå ¬å¼ã«ãµãã¼ããã¦ããã®ã¯Azure Pipelineã®artifactsãããã§ã¯ãªãã ãããã
ä¸æ¹ã§ãdockerãk8sçéã§ã¯ãã®è¦åãå®ã£ããªãªã¼ã¹ããã¼è¡ã£ã¦ãã話ãèããã¨ãããããã«ãããã³ã³ããã«ã³ãããããã·ã¥ãªã©ä¸æã«ç¹å®ã§ããtagãä»ãã¦ããããã®ã³ã³ããããããã¤ããæ¤è¨¼ç°å¢ã§åä½ç¢ºèªã確å®ã«åãtagãæå®ãã¦æ¬çªç¨ã®k8sã«ãããã¤ã¨ããæµãã
5.3.5 åå¤æ´ã¯ç´ã¡ã«ãã¤ãã©ã¤ã³å ¨ä½ãéãæããªããã°ãªããªã
ãã«ãã¯1hãã¨ãåãå ¥ããã¹ãã¯å¤ä¸ããã£ãã·ãã£ãã¹ãã¯é±æ«ã®ããã«ç°ãªãã¹ã±ã¸ã¥ã¼ã«ãè¡ã£ã¦ã¯ãªããªãã¨ãããã¨ã
ãã«ããã¦ããããã¹ãã¯çæéã§çµããä¸æ¹ãåãå ¥ããã¹ãã¯æéãããããã®ãããã§ããã«ã1ã«å¯¾ãã¦ã®åãå ¥ããã¹ããçµããã¾ã§ã®éã«ãã«ã2,3,4ã¾ã§çµãã£ã¦ããå ´åã次ã®åãå ¥ããã¹ãã¯ãã«ã4ã®ãã®ã使ãã
ããã¯å³ããªãã¨èª¬æãé£ããããä»æ¥ã§ã¯CircleCIãBitriseãªã©ã§åãã©ã³ãã¸ã®pushããã¥ã¼ã«ç©ã¾ããå ´åã次ååãã¨ãã«ææ°ã®ã³ããã以å¤ã¯ãã¥ã¼ã«ç©ã¾ãããã«ãäºå®ãç ´æ£ãããã¨ãããªãã·ã§ã³ãæãè¿ãæåã
ãããç®æãã¨ããã¯ãã¤ãã¬ã¼ã·ã§ã³ãµã¤ã¯ã«ããªãã¹ãçãä¿ã¤ãã¨ã§ãåãå ¥ããã¹ãã失æããã¨ãã«ã©ã®ãã«ããåå ã ã£ãã®ããçªãæ¢ãããããããã¨ãç®çã§ããã
Jenkinsã§ãããã¨ä¾¿å©ãããªã®ã ãã©ããããå®ç¾ãããããªJenkinsãã©ã°ã¤ã³ã®è©±ãèãããã¨ããªãã®ã§ãç°¡åã«å®ç¾ãããã¨ã¯ã§ããªãããã
6.5.2 ç°å¢è¨å®ããã¹ããã
ãã«ãç°å¢ããããã¤å ã®ç°å¢ãæ£ããè¨å®ããã¦ãããããã¹ãããå¿ è¦ãããã®ã§ãç°¡åãªã¹ã¢ã¼ã¯ãã¹ããªã©ãç¨æãã¾ãããã¨ãããã¨ã
6.6.1 常ã«ç¸å¯¾ãã¹ã使ã
ç¹ã«èªãå¿ è¦ããªãã絶対ãã¹ã«ããã¨ãã«ããã·ã³ã®ã¦ã¼ã¶ã¼åãªã©ã«ãå½±é¿ããã¦ãã¾ãããJenkinsã«ããã¦ã¯ã¸ã§ãã¯workspaceã®ãã£ã¬ã¯ããªæ¯ã«éé¢ããã¦ããã ããªã®ã§ãç¸å¯¾ãã¹ã使ããªãã¨ç°¡åã«ç ´ç¶»ãã¦ãã¾ãã
6.6.5 ãã¹ãã失æãã¦ããã«ãã¯ç¶ãã
ãã«ãã·ã¹ãã ã¯ã¿ã¹ã¯ã失æããæç¹ã§å ¨ã¦ãçµäºãããã®ãããã©ã«ãæåã ããããã¯ãã£ãããªãã®ã§ãã®ã¿ã¹ã¯ã失æããã¨ããäºå®ãè¨é²ãã¦å¾æ®µã®ã¿ã¹ã¯ãå®è¡ãã¾ãããã¨ãããã¨ã
ä¾ãã°ãã¦ããããã¹ããã¤ã³ãã°ã¬ã¼ã·ã§ã³ãã¹ããã¹ã¢ã¼ã¯ãã¹ããåå¨ããå ´åãã¦ããããã¹ãã失æããå ´åã«ã次ã«ã³ããããããã¾ã§ã¤ã³ãã°ã¬ã¼ã·ã§ã³ãã¹ããå®è¡ãããªãã®ã¯æéã®ç¡é§ã§ããã
ã¨ããã®ãæ¬ã®ä¸»å¼µãªã®ã ãã©ãLintã¯ã¨ãããã¦ããããã¹ããè½ã¡ã¦ãããå¾æ®µã®ã¤ã³ãã°ã¬ã¼ã·ã§ã³ãã¹ããè½ã¡ãã¯ããªã®ã§å®è¡ããã®ã¯ããã£ã¦ãã«ããã·ã³ã®ç¡é§ä½¿ããªæ°ããããï¼
7.2.2 ã©ãããã¨ãã«ã³ãããã¹ãã¼ã¸ãæ¢ããã¹ããï¼
ã³ã³ãã¤ã«ã¨ã©ã¼ããã¹ãã失æããã¨ãã«ãã«ããfailã«ãªãã®ã¯å½ç¶ã ããã³ã¼ãå質ããã¹ãã®ã«ãã¬ãã¸ãä½ãå ´åã§ããããéãã®ãï¼ã¨ããåé¡ã
ä¾ãã°ãã¹ãã«ãã¬ãã¸ã60%æªæºãªãã³ãããã¹ãã¼ã¸ã¨ãã¦ã¯failããã80%æªæºãªãééã¯ããããã¹ãã¼ã¿ã¹ã¯é»è²ã«ãã¦ããã¨ããæ¦ç¥ãããããã ãããã®ãããªçç±ã§failãããå ´åã«ã¯ããã¼ã ã®åæãã¡ããã¨å¾ããã¦ããªãã¨ããã£ã¦ç¶ç¶çã¤ã³ãã°ã¬ã¼ã·ã§ã³ãç ´ç¶»ãã¦ãã¾ããã¨ã«æ³¨æã
ä»æ¥ã§ã¯GitHubã¨é£æºã§ããDangerããCodecovã®ãããªã«ãã¬ãã¸ãµã¼ãã¹ã使ããã¨ã§ç°¡åã«å®ç¾ã§ããããã«ãªã£ã¦ããã
7.3.1 ææç©ãªãã¸ããª
ãã¹ãã¬ãã¼ãããã¤ããªã¨ãã£ãã³ãããã¹ãã¼ã¸ã®ã¢ã¦ããããã¯å¾ã§åå©ç¨ã§ããããã«ã©ããã«æ ¼ç´ãã¦ãããgitãªã©ã«ã³ãããããæ¹æ³ãããããåºæ¬çã«åãã½ã¼ã¹ã³ã¼ãã§ãã«ãããå ´åã«ã¯åãææç©ãå¾ãããã¯ããªã®ã§ããããã³ãããããã®ã¯ç¡é§ã
Jenkinsãªã©ã®ã¤ã³ãã°ã¬ã¼ã·ã§ã³ãµã¼ãã¼ã¯èªåã§ææç©ãªãã¸ããªã®æ©è½ãæä¾ãã¦ããã®ã§ãåºæ¬çã«ã¯ããã使ãã°ãããJenkinsã«ã¯fingerprintã¨ããæ©è½ãããã®ã§ã1ã¤ã®ãã¤ãã©ã¤ã³ä¸ã§å段ã®ææç©ãå¾æ®µã§ééããªãåãåºãã®ã¯é£ãããªãã£ãã¯ãã
ããå°ãçºå±ãããã¨ãJenkinsã使ã使ããªãã«éããS3ãGCSãªã©ã®ã¯ã©ã¦ããªãã¸ã§ã¯ããµã¼ãã¹ãææç©ãªãã¸ããªã¨ãã¦ä½¿ããã¨ãå¯è½ãJenkinsã«ææç©ãç½®ãã¨ãã£ã¹ã¯ã¹ãã¼ã¹ãå§è¿«ããã®ã§ã容éã«å¯¾ãã¦å¾é課éå¶ã®ãµã¼ãã¹ã使ãã»ããç¾ä»£ã§ã¯ä¾¿å©ã§ããã
ãããã¯ã2018å¹´é ããGitHub, Azure, GCP, AWSãªã©ãããã£ã¦åè¨èªã®ãã©ã¤ãã¼ãããã±ã¼ã¸ãªãã¸ããªãµã¼ãã¹ãæä¾ããããã«ãªã£ãã®ã§ãããããæ´»ç¨ããã¨ããã«ç°¡åã«å®ç¾ã§ãããããããªãã
8.5.2 ããã»ã¹å¢çã»ã«ãã»ã«åã»ãã¹ã
ãã¹ãã®ããã ãã®ããã¯ãã¢ã¯ãªãã¹ãä½ããªãã¹ãã§ããã代ããã«ãã¹ãã§ã¯ã¹ã¿ããªã©ã®ãã¹ãããã«ã«ç½®ãæããã¹ãã
ããã¯ãã¢ããã¹ãç¨ã³ã³ãã¼ãã³ãã¯ãã¾ããªã¡ã³ããå¿ è¦ã«ãªã£ã¦ãã¾ãããæ¬çªã«ãããã¤ãããªãããã«æ³¨æããå¿ è¦ãããã¨ãããã¡ãªãããããããã
8.5.4 ãã¹ãããã«ãå©ç¨ããã
åãå ¥ããã¹ãã§ãå¤é¨ã·ã¹ãã ã使ãé¨åãªã©ã¯ãªãã¹ããã¹ãããã«ã«ç½®ãæããã¹ããèªååãå ¥ããã¹ãã¯ã¦ã¼ã¶ã¼åãå ¥ããã¹ãã¨ã¯éãã
å¤é¨ã·ã¹ãã ã¯ãå¶å¾¡å¯è½ããªãã®ã§ãªãã®ã§ããã¹ãã¯ä¸å®å®ã«ãªããã¡ã§ã§å¤é¨ã·ã¹ãã ã«è² è·ãããããã¦ãã¾ããã¨ããããããããããå¤é¨ã·ã¹ãã ã¨ã®æ¥åç¹ããã¹ãããã«ã«ç½®ãæãããããããªè¨è¨ã¨ããã¹ãã§ããã
8.6.0 åãå ¥ããã¹ãã¹ãã¼ã¸
åãå ¥ããã¹ãã失æãããããã¯ãããã¤ãã¦ã¯ãªããªããåãå ¥ããã¹ãã失æããå ´åã¯ããã«åå ãçªãæ¢ãã¦ä¿®å¾©ããå¿ è¦ãããã
ãããå°ã楽ã«ããæ¹æ³ã¨ãã¦ããã¹ãå®è¡ä¸ã®ç»é¢ãé²ç»ãã¦ããããã¹ãã¬ãã¼ãã¨ä¸ç·ã«ææç©ã¨ãã¦ä¿åãã¦ããã¨å½¹ã«ç«ã¤ã
ä»æ¥ã§ã¯Seleniumãã¢ãã¤ã«ã®E2Eãã¹ãåºç¤ãæä¾ãããµã¼ãã¹ã®å¤ãããã¹ãä¸ã®é²ç»ãæä¾ãã¦ããã¦ããã®ã§ããããã£ããµã¼ãã¹ãé¸æããã°ãæ軽ã«éæã§ããã
8.6.2 ãããã¤ã¡ã³ããã¹ã
åãå ¥ããã¹ããè¡ãç°å¢ã¯çä¼¼æ¬çªç°å¢ã«ãªãã®ã§ããããã¤æ¦ç¥ãæ£ããåä½ãããã確èªãããã¨ãå¯è½ã«ãªããåãå ¥ããã¹ãã¯ä¸è¬çã«å®è¡æéãç¸å½ãããã®ã§ããã®ãããã¤ç¢ºèªããããã¤ãã¹ãã¨ãã¦ããããããã¤ãã¹ãã失æããå ´åã¯åãå ¥ããã¹ãã®å®äºãå¾ ããã«çµäºããããã¨ã§æéãç¯ç´ã§ããã
ããã¯ä¸è¬çãªwebãµã¼ãã¼ãªãå¯è½ãªè©±ãä»æ¥ã§ã¯VMãDockerãªã©ä»®æ³åæè¡ãããªãé²ãã ã®ã§ããããã¤ãã¹ããè¡ãã®ãæ ¼æ®µã«æ¥½ã«ãªã£ã¦ããã¯ãã
11.3.1 åºç¤ã¸ã®ã¢ã¯ã»ã¹ãå¶å¾¡ãã
ãã¹ãç°å¢ãæ¬çªç°å¢ããä½ãèµ·ããã¨ãã«èª°ãã©ãããå¤æ´ãè¡ã£ãã®ã追跡ã§ããªãã¨åå ã®ç¹å®ãé£ããã¨ãã話ããã¡ãããã¹ãç°å¢ã®å¤æ´ã«ã¤ãã¦ã¯æ¬çªãããç°¡åã«ç³è«ãéãããã«ãªã£ã¦ããã¹ãã§ããã
ãã®è©±é¡ã¯Jenkinsã®ãã«ããã·ã³ãããã話ãç³è«ãå¿ è¦ãªã»ã©ã¬ãã¬ãã«åºããå¿ è¦ã¯ãªãã¨æãããããã¦ã©ãããä½æ¥ãããã®ãè¨é²ã¯æ®ãã¦ã»ããã
11.3.2 åºç¤ã¸å¤æ´ãå ãã
å¤æ´ã¯ãã±ããã§ç®¡çãã¦ãå¤æ´å 容ããã¨ãããã°ã§ç£æ»ã§ããããã«ãã¦ããããããã¤ã®è¨é²ã¯æ®ããã¾ãã¯ãã¹ãç¨ã®çä¼¼æ¬çªç°å¢ã§ãã¹ããã¦ããå£ããªããã¨ã確èªããã
å¤æ´ã¯Puppetãªã©ã®ãã¼ã«ã§è¡ããå¤æ´ã®ããã®ã¹ã¯ãªããã¯ãã¼ã¸ã§ã³ç®¡çãããã¹ãã
ãã«ããã·ã³ã¸ã®Ansibleã®é©ç¨ã§ã©ã®ãã·ã³ã«ã©ãã¾ã§ã®å¤æ´ãé©ç¨ãããã¯åé¡ã«ãªããã¨ããã¾ã«ããããé ã§è¦ãã¦ãã¦ãªãã¨ãéç¨ãã¦ããç¶æ ã«è¿ãã®ã§è³ãçããããããAnsibleã¯Terraformãªã©ã®ããã«ç¶æ ã«åæããããã®ã§ã¯ãªãã¦ããã¾ã§åãªãã¹ã¯ãªãããªã®ã§ããè¨å®ãå ¥ãããå ´åã¯æ®éã«æ¸ãã°ãããããè¨å®ãå¤ããå ´åãå¤ãããã®å¦çãããããè¨è¿°ãã¦ããå®è¡ããå¿ è¦ãããã®ã§æ¬å½ã«ããã©ãããã
ãã¯ããããã¤å ã®ç°å¢ã¯æ¯åã¾ã£ãããªç¶æ ãããããã¸ã§ãã³ã°ãè¡ãããããã¯VMãã³ã³ãããªã©ã®ä»®æ³ç°å¢ã§ããæ¹ãå§åçã«æ¥½ã
11.4.2 é²è¡ä¸ã®ãµã¼ãã¼ç®¡ç
æ°ãããã·ã³ãæ¥ããæ§æãåæã«å¤ãããããã¨ããªãããã«ãã¾ã管çè 以å¤ã®ãã°ã¤ã³ãå¶éãã¦ããèªååã¹ã¯ãªããã§ã»ããã¢ãããè¡ãããã¨ã¯Puppetãªã©ã®ãã¼ã«ãåãã·ã³ã管çä¸ã«ããã¦å¤æ´ãé©ç¨æ¸ã¿ã®ç¶æ ãã©ãããç£è¦ãã¦ãããã
èªåã¯ä½¿ã£ããã¨ããªãããç¾ä»£ã ã¨Ansible Towerãªã©ä¸å¤®é権çã«ã¹ã¯ãªãããå®è¡ãããç£è¦ã®å½¹å²ããã¦ãããã®ããï¼èªåã§ããã®ã§ããã°ãServerspecã¿ãããªãã·ã³ã®ç¶æ ããã¹ãããããã®ã¹ã¯ãªãããç¨æãã¦ãããã¤å¾ãcronãªã©ã§å®æçã«åãã·ã³ãã¡ããã¨ã¹ã¯ãªããã§å®ç¾©ãããæå³ããç¶æ ã«ãªã£ã¦ãããã©ããã®ç¢ºèªãè¡ãæ¹æ³ãã§ãããã
11.5.4 è¨å®APIãæ¢ã
DBãªã©ã®ããã«ã¦ã§ã¢ããã¹ãç¨ã«èªåã§è¨å®ããæ¹æ³ã®é¸æè¢ã®æèãçæ³ã®ããã«ã¦ã§ã¢ã¯ãã¤ããªã§ã¯ãªãããã¹ããã©ã¼ãããã®è¨å®ãã¡ã¤ã«ã§å ¨ã¦ãè¨å®ã§ããã¿ã¤ãã ãããããã§ããªãå ´åã®å¦¥åæ¡ã¨ãã¦è¨å®APIããåå¨ããã®ã§ããã°è¨å®DSLãèªåã§ä½ããã¨ã«ãããè¨å®ãã¡ã¤ã«ã«ããæ§æ管çãèªåã®æå ã«åãæ»ããã¨ãã§ããã
ä»æ¥ã§ã¯AnsibleãTerraformãªã©ããã®æã®ã¢ããã¼ãã«ãã£ã¦AWSãGCPã®æ§æ管çãããããã®DSLã§æ¸ããã¨ãã§ããããã«ãªã£ã¦ããã
11.7.1 ä»®æ³ç°å¢ã管çãã
ä»®æ³ãã·ã³ã®ã¤ã¡ã¼ã¸ãåä¸ãã¡ã¤ã«ã§æ±ãããã¨ã®å©ç¹ã®è©±ã稼åä¸ã®VMãç°¡åã«ã³ãã¼ã§ãããã¨ã ããå©ç¹ã§ã¯ãªãããã¼ã«ã«ãã£ã¦ã¯ç©çãã·ã³ã®ã¹ãããã·ã§ããããã£ã¹ã¯ã¤ã¡ã¼ã¸ã«å¤æãããã¨ãå¯è½ãªã®ã§å®éã®æ¬çªç°å¢ã®ã¹ãããã·ã§ãããVMåãããã¨ã§ç¶ç¶çã¤ã³ãã°ã¬ã¼ã·ã§ã³ããã¹ãã«ä½¿ããã¨ãã§ããã
ä»ã«ãããã¤ãå©ç¹ãããã
- æ°ããç°å¢ã®ãããã¸ã§ãã³ã°ã¨ãã¦VMããã®ã¾ã¾ä½¿ãã
- VMã«å¯¾ãã¦èªåã§ã½ããã¦ã§ã¢ã®ã¤ã³ã¹ãã¼ã«ãè¨å®ãããå¾ã®ç¶æ ãããã«ãã³ãã¬ã¼ãVMã¨ãã¦ä¿åãã¦ä½¿ãåãã
- æåã§è¨å®ããã¦ãã¾ã£ã¦ããç°å¢ãã¾ãã¯VMåãããã¨ã§ãå°ããã¤èªåæ§ç¯ã«ã·ããããéç¨ã®ä¸ã§ã¾ãã¯åããã¨ãä¿è¨¼ããã¦ããç¶æ ããã¹ã¿ã¼ãã§ãã
- ã¤ã³ã¹ãã¼ã«ãè¨å®ãèªååã§ããªãã½ããã¦ã§ã¢ãVMåãããã¨ã§ãè¨å®æ¸ã¿ã®ç¶æ ãè¤è£½ãããã¨ãå¯è½ã«ãªã
ä»æ¥ã§ã¯ãGitHub ActionsãBitriseãªã©ã®CIãµã¼ãã¹ãå®è¡ç°å¢ã¨ãã¦æä¾ãã¦ããVMããã®é¡ã®è©±ãä¸æãæ´»ç¨ãã¦ãããæ§ã ãªè¨èªã使ç¨ãããã¼ã«ãSDKãå ¨é¨å ¥ãã®ç¶æ ã§ä¿åãããVMãæä¾ãã¦ããã¦ããã®ã§ãã¦ã¼ã¶ã¼å´ã¯ããã¦ãã®å ´åã«ããã¦åãã¼ã«ã®ã¤ã³ã¹ãã¼ã«ããè¡ãå¿ è¦ã¯ãªãã
ç¹ã«Bitriseã«ãããmacOSã®VMä½æã¢ããã¼ãã¯ã¨ã¦ãå¹ççã§ãmacOSã®VMã«ããããã¯æåã§Xcodeãã¤ã³ã¹ãã¼ã«ããç¶æ ããã¼ã¹ã¤ã¡ã¼ã¸ã¨ãã¦ä¿åãã¦ããããã®VMã«å¯¾ãã¦Ansibleã§ãã®ä»ã®ãã¼ã«ãã¤ã³ã¹ãã¼ã«ããå®æå½¢ã¤ã¡ã¼ã¸ãã¦ã¼ã¶ã¼ã«æä¾ãã¦ãããXcodeã¯Appleãå ¬å¼ã®ã¤ã³ã¹ãã¼ã«ãã¼ã«ãæä¾ãã¦ããªãããã§èªåã¤ã³ã¹ãã¼ã«ãè¡ãã®ã¯å¤§å¤ãªå´åãä¼´ãã®ã§ãããã ãæåã§ã¤ã³ã¹ãã¼ã«ãè¡ãã®ã¯å®å ¨ã«çã«ããªã£ã¦ããã
12.4.2 ã¢ããªã±ã¼ã·ã§ã³ã®ãããã¤ããã¼ã¿ãã¼ã¹ã®ãã¤ã°ã¬ã¼ã·ã§ã³ããåé¢ãã
ã¢ããªã±ã¼ã·ã§ã³ã®ãã¼ã¸ã§ã³ãä¸ããéã«ãDBã¹ãã¼ãã¨æ·±ãé¢ä¿ãã¦ããã¨ä¸¡æ¹ãåæã«æ´æ°ããå¿ è¦ããããããããã¨ä¸¡æ¹ãå ±ã«ãã¼ã«ããã¯ãããã®ãé£ãããªãã®ã§ãã®å¯¾çã®è©±ã
æ¹æ³ã¨ãã¦ã¯ãã¢ããªã±ã¼ã·ã§ã³ã®ã³ã¼ãå´ã§æ°æ§ã®DBã¹ãã¼ã両æ¹ã§åä½ããããã«å¯¾å¿ããã¦ãããã¢ããªã±ã¼ã·ã§ã³âDBã¹ãã¼ãã®é çªã§ãããã¤ãããã¨ãããã®ãã¢ããªã±ã¼ã·ã§ã³ããããã¤ããæç¹ã§ãªã«ãåé¡ãããã°ã¢ããªã±ã¼ã·ã§ã³ã ãããã¼ã«ããã¯ãããã°ãããã¢ããªã±ã¼ã·ã§ã³ãå®å®ããã¨å¤æã§ããã°DBããããã¤ããã
ã¢ããªã±ã¼ã·ã§ã³ã¨DBã®ãããã¤ãåå²ããæ¹æ³ã¯ããã¼ã¡ã³ãã§ã¢ããªã±ã¼ã·ã§ã³ã®ãã¼ã¸ã§ã³ãä¸ãããã¨ããã¨ãã«ã使ãããæ¹æ³ãããããªããèªåãéå»ã«çµé¨ããããã¸ã§ã¯ãã§ã¯éé ã®DBâã¢ããªã±ã¼ã·ã§ã³ã§ã ã£ããããªè¨æ¶ããããããããããã¨ãææ³ã¯åãã¯ãã
12.5.3 ãã¹ãã®åé¢
åã ã®ãã¹ãããäºãã«å½±é¿ãä¸ããªãããã«ä¿è¨¼ããããããDBã使ãå ´åã§ãå®ç¾ããæ¹æ³ãRDBMSã使ã£ã¦ããã®ã§ããã°ããã©ã³ã¶ã¯ã·ã§ã³æ©è½ã使ãã®ããã£ã¨ãç°¡åã
ãã¹ãéå§æç¹ã§ãã©ã³ã¶ã¯ã·ã§ã³ãä½æãããã¹ãä¸ã®DBæä½ã¯å ¨ã¦ãã©ã³ã¶ã¯ã·ã§ã³å ã§è¡ãããã¹ããçµãã£ãã¨ãã«ãã©ã³ã¶ã¯ã·ã§ã³ããã¼ã«ããã¯ãããããã ãã§ä»ã®ãã¹ãããäºãã®DBã«å½±é¿ãä¸ããªãããã«ã§ããã
å¥ã®æ¹æ³ã¨ãã¦ã¯ãä½ãããã®æ©è½ãè¦åã使ã£ã¦ãã¹ãæ¯ã®ãã¼ã¿ãåé¢ãããã¨ã
ããã¯ããã®æã®ãã¹ãDBã®åé¢ã«é¢ããçºæ³ããããã©ããã¨ãããè¦è¶ããã¢ããªã±ã¼ã·ã§ã³è¨è¨ã«ãªã£ã¦ããã次第ã
RDBMSã使ã£ã¦ãã¦ã1ãªã¯ã¨ã¹ãä¸ã§è¤æ°åãã©ã³ã¶ã¯ã·ã§ã³ããã¦ããå ´åã¯ä½ããã®å·¥å¤«ãå¿ è¦ã ããããããããã©ã³ã¶ã¯ã·ã§ã³ããµãã¼ããã¦ããªãNoSQLãªã©ã使ã£ã¦ããå ´åã¯ãã¼ã¿ãã¼ã¹ãã®ãã®ã®ã¤ã³ã¹ã¿ã³ã¹ãåé¢ããã¨ãããã¼ãã«åã§åé¢ã§ãããããªã³ã¼ãè¨è¨ã«ãªã£ã¦ããããªã©ã¢ããªã®åæè¨è¨ããèæ ®ã§ãã¦ããªãã¨å®ç¾ã¯é£ããã
13.2.3 æ½è±¡åã«ãããã©ã³ã
ãã©ã³ããåãã¨ãããã¨ã¯æ¬è³ªçã«ç¶ç¶çã¤ã³ãã°ã¬ã¼ã·ã§ã³ãé£ããããã¨ããæèã«ããã¦ããã©ã³ãã使ããªãã¢ããã¼ãã®è©±ã
ãã©ã³ããåã£ã¦å¤§è¦æ¨¡ã«ã³ã¼ããæ¹å¤ãããä¾ã¨ãã¦ãªãã¡ã¯ã¿ãªã³ã°ãããããã©ã³ããåããã«è¡ãå ´åã¯ãã¾ãæåã«æ½è±¡ã¬ã¤ã¤ãä½æãããã®æ©è½ãå¼ã³åºãå¥ã®ã³ã¼ããæ½è±¡ã«ä¾åããããããã¦ãªãã¡ã¯ã¿ãªã³ã°ãæ½ãæ°ããå®è£ ãè£ã§ä½æãã¦ãããå®æããã¨ãã«æ½è±¡ã¬ã¤ã¤ãæ¸ãæãã¦æ°ããå®è£ ã使ãããã«å¤æ´ããã¨ããæ¹æ³ã
ä»æ¥ã§ã¯ãã®è©±ã¯ãããããfeature flagãããfeature toggleãã®èãæ¹ã«ä½¿ããã¦ããããã«æãããã®æã®æ¹æ³ãå®ç¾ããããã«æãç°¡åãªãã®ã¯IFåå²ã ããããã¹ãã¼ããªæ¹æ³ãèããã¨èªç¶ã«ãã®æ½è±¡ã¬ã¤ã¤ã®ææ³ã«ãã©ãçãã¨æãã
ãfeature flagããå¿ è¦ã«ãªã£ã¦ããçç±ãããã©ã³ããåã£ã¦å¤§è¦æ¨¡éçºãè¡ãã¨ãã¼ã¸ä½æ¥ã®ã³ã¹ããæ¤è¨¼ã³ã¹ããä¸ãããããã£ã1ãã©ã³ãã§éç¨ããã¨ãããã®ã ã£ãã¨è¨æ¶ãã¦ããã®ã§ãã¾ãã«ãã®æ¬ã«æ¸ããã¦ãããã©ã³ããåãã³ã¹ãã®è©±ã¨ä¸è´ãã¦ããã
13.5.4 æ éãªæ¥½å¤©ä¸»ç¾©
ãããã«ãã®ä¾åç©ã¯ããããã¾ããã«ããå¿ è¦ã§ãªã«ãã«ä¾åãã¦ãããã¤ã¾ãA â B â Cã®ãããªä¾åã°ã©ããä½ããã¨ãã§ãããããããã®ä¾åç©ã®ãã¼ã¸ã§ã³ãåºå®å¯è½ã ã¨ãã¦ãã©ããã£ã¦å®å®ãããã«ãã¨ãã¼ã¸ã§ã³ã¢ããã両ç«ããããã¨ããæ¦ç¥ã®è©±ã
ä¾åé¢ä¿ã«staticã¨fluidã¨ããã©ãã«ãåãããstaticã¯å¸¸ã«ãã¼ã¸ã§ã³ãåºå®ããã¦ãããä¸æ¹ã§fluidã¯ãã¼ã¸ã§ã³ãæµåçãªã®ã§å¸¸ã«å¤ãããA(static v1) & B(fluid v2) â Cã¨ããé¢ä¿ã§ãã«ããããã¨ããä»®ã«Bãv3ã«ä¸ãã£ãããªã¬ã¼ã§ãã«ããããå ´åã«ãã«ãã失æããã¨Bã¯"guarded"ã¨ããã©ãã«ã«å¤åããv2ã§åºå®ããããguardedã¯åã®ãã¼ã¸ã§ã³ã§ããã°ãã«ãã«æåããããæ°ãããã¼ã¸ã§ã³ã ã¨ä½ããåå ã§ãã«ãã«å¤±æããã¨ãããã¨ãªã®ã§æ©æ¥ãªèª¿æ»ãå¿ è¦ã¨ããæå³ã«ãªãã
æ¦å¿µã¨ãã¦ã¯ãããããããä»æ¥ã§ã¯å²ã¨ä¸è¬çãªæ¦å¿µã«ãªã£ã¦ããæ°ããããåè¨èªã®ããã±ã¼ã¸ç®¡çãã¼ã«ã§ã¯ä¸è¬çã«ä¾åã®ãã¼ã¸ã§ã³ã"=", "â¥"ãªã©ã®çå·ã»ä¸çå·ã§åºå®åãããæµåçã«å¤ããããã¦ããããããã¯gitã®submoduleã§ä¾åãªãã¸ããªã®ã³ãããããã·ã¥ãåºå®ããããsubmoduleã使ããªããªã©ã®æ¹æ³ã§å¸¸ã«ææ°ã®ã³ããããåã£ã¦ããããªã©ã
ãã ãCIã¨é£åãã¦"guarded"ã®æ¦å¿µã¾ã§å®ç¾ã§ãã¦ãããã¼ã«ããµã¼ãã¹ã¯è¦ããã¨ããªããå¼·ãã¦è¨ãã°ãDependabotãRenovateã®ããã«ä¾åããã±ã¼ã¸ãèªåã§ã¡ã³ããã¦ããããã¼ã«ã¨ãpackage-lock.jsonã®ããã«è¨èªå´ã§ä¾åãã¼ã¸ã§ã³ãåºå®ãããã¼ã«ãæä¾ããã¦ããã¨"gurarded"ã®æ¦å¿µã«è¿ããã¨ã¯éæã§ãã¦ããããã«æãã
v7ããªãªã¼ã¹ããã®ã§æ¹ãã¦firestore-simpleãç´¹ä»ãã¾ã
firestore-simpleã®éå»ã®ã¨ã³ããª
- Firestoreããã£ã¨æ軽ã«ä½¿ããfirestore-simpleãä½ã£ã
- Firestoreããã£ã¨æ軽ã«ä½¿ããfirestore-simpleããã¼ã¸ã§ã³2ã«ãªãã¾ãã
- TypeScriptããFirestoreã使ããããããfirestore-simple v4ããªãªã¼ã¹ãã¾ãã
- firestore-simple v5ããªãªã¼ã¹ãã¾ãã
以åããä½ãç¶ãã¦ãããFirestoreã使ããããããããã®ã©ããã¼ã§ããfirestore-simpleãv7ã«ãªãã¾ãã ð ï¼v6ã¯äºå®ä¸ã®æ¬ çªæ±ãï¼
v7ã§ä»¥åããå®ç¾ãããã£ãjsã®web SDKã«å¯¾å¿ã§ãã¾ãããadmin/web SDKã®ä¸¡æ¹ã«å¯¾å¿ã§ããã®ã¯1ã¤ã®ç¯ç®ã ã¨æãã¦ããã®ã§ãä»åã®ä¿®æ£ç¹ã«å ãã¦ãããããã®firestore-simpleã®ã³ã³ã»ãããåç´¹ä»ãããã¨æãã¾ãã
BREAKING CHANGES
ããã±ã¼ã¸ãä»ã¾ã§ã®firestore-simpleãããadmin SDKç¨ã®@firestore-simple/adminã¨web SDKç¨ã®@firestore-simple/webã¨2ã¤ã«å¥ãã¾ãããä»ã¾ã§ã®firestore-simpleã¯ããã§DEPRECATEDã«ãªãã¾ãã
ããv6ã¾ã§ã®firestore-simpleãã使ãã ã£ãæ¹ã¯ ã以ä¸ã®ããã«ãã¤ã°ã¬ã¼ã·ã§ã³ããé¡ããã¾ãã
npm install @firestore-simple/admin
// old import { FirestoreSimple } from 'firestore-simple' // new import { FirestoreSimple } from '@firestore-simple/admin'
追å æ©è½
firestore-simpleã¯ä»ã¾ã§admin SDKãã対å¿ãã¦ããªãã£ãã®ã§ãããv7ããweb SDKã«ã対å¿ãã¾ãããããã§admin SDKã使ã£ã¦Firestoreã使ããµã¼ãã¼ãCloud Functionsç°å¢ã«å ãã¦ãã¯ã©ã¤ã¢ã³ãããFirestoreã«ã¢ã¯ã»ã¹ããã³ã¼ãã§ãfirestore-simpleã使ããã¨ãã§ããããã«ãªãã¾ããã
ã¤ã³ã¹ãã¼ã«ã¨importã¯ä»¥ä¸ã®ããã«ãªãã¾ãã
npm install @firestore-simple/web
import { FirestoreSimple } from '@firestore-simple/web'
exampleãè¦ã¦ããããã¨åããã®ã§ãããweb SDKã®æ¹ãAPIã¯åºæ¬çã«ä»ã¾ã§ã®admin SDKç¨ã®firestore-simpleã¨å ¨ãä¸ç·ã«ãªã£ã¦ãã¾ãã
ãã ããweb SDKã®ä¸é¨ã®ã¡ã½ãããæã¤admin SDKã«ã¯åå¨ããªããªãã·ã§ã³ã«ã¾ã 対å¿ã§ãã¦ããªãã¨ãããããã¾ããä¾ãã°get()
ãåãåããGetOptionsãªã©ã§ãããããã¯ä»å¾å¯¾å¿ãã¦ããäºå®ã§ãã
æ¹ãã¦firstore-simpleã®æ©è½ç´¹ä»
ããã¾ã§ç´°ã ã¨ç´2å¹´ã»ã©ä½ãç¶ãã¦ããã®ã§ãv1ããæ¯ã¹ãã¨jsããTypeScriptãã¼ã¹ã«å¤æ´ãããã¨ãããæã®ã³ã¼ãã¯å ¨ã¦ç½®ãæããã¾ãããã§ãããFirestoreãããjsããæ±ãããããããã¨ããã³ã³ã»ããã¯å¤ãã£ã¦ãã¾ããã
v1ããæ¯ã¹ãã¨ã¢ãã¼ã«ããããã¤ã³ããããã¤ãå¤ããã¾ããã®ã§ãæ¹ãã¦firestore-simpleã®ä»£è¡¨çãªç¹å¾´ãç´¹ä»ãã¾ãã
ãã¼ã¿ã®åå¾ã¨æ´æ°ãç°¡æ½ã«
ç´ ã®Firestoreã§1ã¤ã®ããã¥ã¡ã³ãã追å ãããããã¼ã¿ãåå¾ããå ´åããã®ãããªã³ã¼ãã«ãªãã¾ãã
const id = await firestore.collection('users').add({ userId: 'alice' }) const doc = await firestore.collection('users').doc(id).get() const data = doc.data()
æ£ç´ã1ã¤ã®ããã¥ã¡ã³ãã追å ããããåå¾ããããã«æ¯åãã®ã³ã¼ããæ¸ãã®ã¯é¢åãããã¨æãã¦ãã¾ããå ãã¦ãæ¯åcollectionãæå®ããå¿ è¦ãããããã³ã¬ã¯ã·ã§ã³åãtypoãã¦ãã¾ãã ãã§å®¹æã«ãã°ã¨ãªãã¾ãã
ããã«ããã®çãã³ã¼ãã®ä¸ã ãã§CollectionReference, DocumentReference, DocumentSnapshotã¨ãã3ã¤ã®Firestoreã®ã¯ã©ã¹ãç»å ´ãã¦ãããæ
£ããã¾ã§ã¯è¤éã«æããã§ããããã¡ãªã¿ã«ãdata()
ã®ã¡ã½ãããæã£ã¦ããã®ã¯DocumentSnapshotã§ããã
ãããã«å¯¾ãã¦èªåãåæã«åã£ãã¢ããã¼ãã¯ã以ä¸ã®ããã«ã³ã¬ã¯ã·ã§ã³æ¯ã«ã©ããã¼ã¯ã©ã¹ãä½ã£ã¦ã¡ã½ãã1ã¤ã§ãã¼ã¿ãåå¾ã§ããããã«ãã¦ãã¾ããã
class UserCollection { constructor() { this.collection = firestore.collection('users') } async fetch(userId) { const docRef = await this.collection.doc(userId).get() return docRef.data() } } const userCollection = new UserCollection() const user = await userCollection.fetch('alice') // id='alice'ã渡ãã ã
ãã®ãããªã¯ã©ã¹ãèªåã§ç¨æããã¨ãCollectionReference, DocumentReference, DocumentSnapshotã®åºå¥ãæèãããã¨ãªããåç´ã«documentã®idã ãã渡ãã¦ä¸ã®ãã¼ã¿ãåå¾ãããã¨ãå¯è½ã«ãªãã¾ããå®ã«ã·ã³ãã«ã§ãã
firestore-simpleã¯ã¾ãã«ãããæ±ç¨åãããã®ã§ããããã®ãããªã¯ã©ã¹ãã³ã¬ã¯ã·ã§ã³æ¯ã«èªä½ããå¿ è¦ããªããªãã¾ããå è¿°ã®ã³ã¼ãã¨åçã®æ©è½ã¯firestore-simpleã ã¨ãã®ããã«ãªãã¾ãã
const firestoreSimple = new FirestoreSimple(firestore) const userCollection = firestoreSimple.collection<User>({ path: 'users' }) const id = await userCollection.add({ userId: 'alice' }) const user = await userCollection.fetch(id)
ActiveRecord風ã§ã¯ã¯ãªã
Firestoreã«éããDBã®ORMã§ããè¦ãã®ã¯ActiveRecordã®ãã¿ã¼ã³ã ã¨æãã¾ããæ¬ä¼¼ã³ã¼ãã§ããã以ä¸ã®ãããªã¤ã¡ã¼ã¸ã§ãã
const user = new User({ userId: 'alice' }) user.age = 20 await user.save() // ããã§DBã«æ¸ãè¾¼ã¾ãã const alice = await User.find({ userId: 'alice') // DBãããã¼ã¿åå¾
ä»ã©ãã§ã¯é常ã«ãããµããORM風ã®APIã§ãããfirestore-simpleã§ã¯2ã¤ã®çç±ããããã¦ãã®ãããªAPIã«ã¯ãã¦ãã¾ããã
1ã¤ç®ã¯åç´ã«ç´ ã®Firestoreã®APIããé¢ããããªãããã«ãããã£ãããã§ããç´ ã®Firestoreãã使ãæ¹ãé¢ãããã¦ãã¾ãã¨ä½ãåé¡ãèµ·ããå ´åã«ã³ã¼ãã追ãã«ãããªã£ã¦ãã¾ããããããã¾ã§èãã©ããã¼ã¨ãªãããã«æèãã¦ãã¾ãã
2ã¤ç®ã¯ãjsçéã«ããã¦ã¯ä½ãå¤ãå
¥ãã¦ããå
¥ãç©ã¨ãã¦ãåãªãObjectï¼{ foo: bar}
ã®ãããªå½¢ï¼ã好ã¾ãã¦ããã¨æãã¦ããããã§ããTypeScriptãããã«ãã®åãªãObjectã«å¯¾ãã¦åãä»ãã¦æ±ãããã¨ããç¹ãéè¦ãã¦ããè¨èªã§ããActiveRecordãã¿ã¼ã³ã¯ã¯ã©ã¹ã¨ã¤ã³ã¹ã¿ã³ã¹ã«ãã£ã¦å®ç¾ããããã®ã§ããããã®ææ³ã¨çéã§ããããfirestore-simpleã§ã¯ãã®ãããªAPIãæä¾ãã¦ãã¾ããã
å¼·åãªåæ¨è«ã¨è£å®
Firestoreã®å¾®å¦ãªç¹ã¨ãã¦ãTypeScriptã§ä½¿ãã¨ãã«CollectionReferenceãDocumentReferenceãªã©ã®Firestoreèªä½ã«ã¯åãä»ãã¦ãã¾ãããåå¾ãã¦ããããã¥ã¡ã³ãã«ã¯åãä¸åä»ãã¦ãã¾ãããã»ã¨ãã©ã®æ¹ã¯doc.data() as User
ãªã©ã¨èªåã§åãä»ãã¦ããã®ã§ã¯ãªãã§ããããã
firestore-simpleã§ã¯ã³ã¬ã¯ã·ã§ã³ãå®ç¾©ããã¨ãã«ããã¥ã¡ã³ãã®åã渡ããã¨ã§ãfetch()
ããããã¥ã¡ã³ãèªåçã«åãä»ãã¾ãããadd()
ãªã©ã®æ´æ°ç³»ã¡ã½ãããåãæ£ããããã§ãã¯ãã¦ããã¾ãã
const userCollection = firestoreSimple.collection<User>({ path: 'users' }) const user = await userCollection.fetch(id) // userã¯èªåçã«Useråã¨ãªã
å®ã¯ãæ¨å¹´Firestoreã«è¿½å ãããwithConverter()
ã使ããã¨ã§ãç´ ã®Firestoreã§ãèªåçã«åãä»ãããã«ãªãã¾ããã
firestore-simpleã¯ããã«å ãã¦åæ
å ±ãå©ç¨ããè£å®ãå¼·åã§ãããwhere()
ãupdate()
ãããã¥ã¡ã³ãã®ãã¼ãè£å®ãã¦ããã¾ããããã«ã¤ãã¦ã¯v4ããªãªã¼ã¹ããã¨ãã®è¨äºã詳ããã®ã§èå³ããã人ã¯è¦ã¦ã¿ã¦ãã ãããã©ã®ããã«è£å®ãããã®ããv4ã®è¨äºããGIFåç»ãã¡ãã«ãè²¼ã£ã¦ããã¾ãã
batchç³»ã®APIã®ä½¿ãåæãåä¸
ããã«ç´ ã®Firestoreã®å¾®å¦ãªç¹ã¨ãã¦ãTransactionãBatchã®APIã®ä½¿ãåæã®æªããæãããã¾ãã
é常ã¯documentReference.get()
ãªã¨ãããTransactionã®ä¸ã§ã¯transaction.get(documentReference)
ã¨APIãå¥ç©ã«ãªã£ã¦ãã¾ã£ã¦ããã®ã§ããããã¯Batchã®æ¹ã§ãåæ§ã§ãã
ããã«ããããããªããTransactionã¨Batchã§ä½¿ãæ¹ãå ¨ãç°ãªã£ã¦ãã¾ãã
// ç´ ã®Firestoreã使ã£ãã³ã¼ã firestore.runTransaction(async(tx) => { // Transactionå ã§ã®å¦ç } const batch = firestore.batch() // set(), update()ãªã©batchã§ã¾ã¨ãã¦è¡ãããå¦ç await batch.commit()
firestore-simpleã§ã¯batchãTransactionã¨åã使ãåæãå®ç¾ããrunBatch()
ã¨ããã¡ã½ãããç¬èªã«è¿½å ãã¾ããã
// FirestoreSimpleã使ã£ãã³ã¼ã await firestoreSimple.runBatch(async (_batch) => { await userCollection.set({ userId: 'alice' }) }) // <- runBatchãæããã¿ã¤ãã³ã°ã§èªåçã«batch.commit()ããã
ãæ°ã¥ãããããã¾ããããç´ ã®Firestoreã§ããã°batch.set()
ã¨æ¸ãå¿
è¦ãããã¨ããããé常éãã®set()
ã®å¼ã³åºãæ¹ã§OKã§ããfirestore-simpleã使ã£ãã¨ãã®runTransaction()
ãåæ§ã®æåã¨ãªãããã«æ¹è¯ãã¦ãã¾ããé常ç¶æ
ãTransactionå
ãBatchå
ã®ããããã®ç¶æ
ã«å¿ãã¦firestore-simpleãã¡ã½ãããè£ã§å¼ã³åãã¦ãã®ãããªé è½ãå®ç¾ãã¦ãã¾ãã
ããã«ãåã«1ã¤ã®ã³ã¬ã¯ã·ã§ã³ã«å¯¾ãã¦é
åã§ã¾ã¨ãã¦add
, set
ãããã ãã¨ããã¦ã¼ã¹ã±ã¼ã¹ã«ä¾¿å©ãªbulkAdd()
, bulkSet()
ãç¨æãã¾ãããéã«idã®é
åã渡ãã¨è¤æ°ã®ããã¥ã¡ã³ããã¾ã¨ãã¦åé¤ãã¦ãããbulkDelete()
ãããã¾ãã
await userCollection.bulkAdd([ { userId: 'alice' }, { userId: 'bob' }, ]) await userCollection.bulkSet([ { id: '1', userId: 'alice' }, { id: '2', userId: 'bob' }, ]) await dao.bulkDelete(['1', '2'])
TransactionãBatchã«ã¤ãã¦ã¯v5ããªãªã¼ã¹ããã¨ãã®è¨äºããµã³ãã«ã³ã¼ãã«ããå°ã詳ããå 容ãããã¾ãã®ã§ãæ°ã«ãªã£ãæ¹ã¯ãã²è¦ã¦ã¿ã¦ãã ããã
ãã¹ãã¯Firestoreã®ã¨ãã¥ã¬ã¼ã¿ã使ç¨
v6ã¾ã§ã¯ãã¹ããå®è¡ããã¨ãã«æ¬ç©ã®Firestoreã使ç¨ãã¦ãã¾ããããv7ã§web SDKã¨admin SDKã®ä¸¡æ¹ã§ã¨ãã¥ã¬ã¼ã¿ã使ç¨ããããã«å¤æ´ãã¾ãããæ¬ç©ã®Firestoreã§ã¯ç¹ã«onSnapshotç³»ã®ãã¹ãã®ä¸å®å®ãã«æ©ã¾ããã¦ãã¾ããããã¨ãã¥ã¬ã¼ã¿ã使ããã¨ã§ã ãã¶ãã¹ããå®å®ãã¾ããã
ã¨ãã¥ã¬ã¼ã¿ã«ãããã¹ãã¸ã®ç½®ãæãã¯ãCIã§ã®å®è¡æ¹æ³ãå«ãã¦ããã¤ãã¯ã¼ã¯ã¢ã©ã¦ã³ããªå¯¾å¿ãå¿
è¦ã ã£ãã®ã§è¦å´ãã¾ãããFirestoreã®ã¨ãã¥ã¬ã¼ã¿ã使ã£ããã¹ãã«èå³ãããæ¹ã¯GitHubã§å
¬éããã¦ããã³ã¼ãã®package.json
ã__tests__/util.ts
ãªã©ãåèã«ãªãã¨æãã¾ãã
ä»å¾ã®å±æ
v7ã§è¿½å ããweb SDKãã»ã¨ãã©ã®æ©è½ã¯å¯¾å¿æ¸ã¿ã§ãããåé ã®æ¹ã§æ¸ããããã«ä¸é¨ã®ã¡ã½ããã§admin SDKã«ã¯åå¨ããªãã£ããªãã·ã§ã³ãæªå¯¾å¿ãªã®ã§ã次ã®ãã¼ã¸ã§ã³ã§ã¯ãããå©ç¨å¯è½ã«ãã¾ãã
æ¬å®¶Firestoreãä½ãããæ°æ©è½ãçºè¡¨ããããããã対å¿ãã¦ããããã¨èãã¦ãã¾ãããããããåã ãã欲ããã¨æã£ã¦ããAPIããã¥ã¡ã³ããæ´åãã¦ããããã¨æã£ã¦ãã¾ããTypeScriptãªãããæãã®ããã¥ã¡ã³ããèªåçæã§ããã¯ãã»ã»ã»ï¼
FirestoreãFirebaseèªä½ãã¾ã ã¾ã é²åã®ã¹ãã¼ããè½ã¡ã¦ããªããããfirestore-simpleãå¼ãç¶ãéçºã»ã¡ã³ãããã¦ããäºå®ã§ããfirestore-simpleããã²ä½¿ã£ã¦ã¿ã¦ãã ããï¼
CircleCI Orbsã®ç¾å³ããã¨ããã ãã使ãã ãä¾ãã°restore_cacheãæ²æ» ããã
ã¯ããã«
CircleCI 2.1ã«ãªã£ã¦Orbsã¨ããæ°æ©è½ãç»å ´ãã¾ããããã¿ãªããæ´»ç¨ãã¦ããã§ããããï¼ å é§è ã®æ¹ã ãOrbsã«ã¤ãã¦ã®ããã°ãæ©éæ¸ãã¦ããã¦ãã¾ããããã®å¤ãã¯èªåã§Orbsãä½ãè¨äºã§ããã
Orbsã¯èªåã§ä½æããã ãã§ãªããCircleCIå ¬å¼ã誰ããä½æãã¦å ¬éããOrbsã使ããã¨ãå¯è½ã§ããããã®ãããªãµã³ãã«ã³ã¼ãã解説è¨äºãã¾ã ã¾ã å°ãªãç¶æ³ã§ããå®éã«èªåãCircleCIå ¬å¼ã®Orbsã使ç¨ãããã¨ããã¨ãã«ãµã³ãã«ãå°ãªãã¦å°ã£ãã®ã§ãèªåã§Orbsãä½ããªãã¦ã使ãã ãã§ååã¨ãã人åãã«è§£èª¬ããã¾ãã
Before & After
ã¾ãã¯ãµã³ãã«ãç´¹ä»ãã¾ããBabelãTypeScriptã§npm run build
ãå®è¡ããã¨ããjséçºã§ã¯æ¥å¸¸çã«è¦ãããconfig.ymlã§ãã
version: 2 jobs: build: docker: - image: circleci/node:latest working_directory: ~/repo steps: - checkout - restore_cache: keys: - v1-dependencies-{{ checksum "package.json" }} - v1-dependencies- - run: npm install - run: name: build command: npm run build - save_cache: paths: - node_modules key: v1-dependencies-{{ checksum "package.json" }} workflows: version: 2 build: jobs: - build
ããããOrbsã使ãã¨ãã®ããã«æ¸ãã¾ãã
version: 2.1 orbs: # https://circleci.com/orbs/registry/orb/circleci/node node: circleci/[email protected] # circleci/nodeã®Orbsã`node`ã¨ããååã§åç §ãã jobs: build: executor: # nodeã®Orbsã«ãã£ã¦image: 'circleci/node:latest'ã¨åãã«ãªã name: node/node tag: "latest" working_directory: ~/repo steps: - checkout - node/with-cache: # ããã©ã«ãã¯~/project/node_modulesããã£ãã·ã¥ããã®ã§working_directoryãå¤æ´ããå ´åã¯ããã«åããã dir: ~/repo/node_modules cache-version: v1 steps: - run: npm install - run: name: build command: npm run build workflows: version: 2 build: jobs: - build
Orbsã«ãã£ã¦restore_cache
, save_cache
ãé è½ããã¦ããã®ãåããã§ããããã
ãã£ãã·ã¥å¨ãã«ã¤ãã¦ã¯CircleCIã®ãµã³ãã«ã³ã¼ããã³ãããã¦ãã ãã®äººã大åã§ã¯ãªãã§ãããããæ¬å½ã¯æé»çã«ãã£ãã·ã¥ãã¦æ¬²ãããããã§ãããCircleCI 2.0ããã¯ãã£ãã·ã¥ã³ã³ããã¼ã«ãå«ãã¦å
¨ã¦ã¦ã¼ã¶ãé¢åãè¦ãä»æ§ã¨ãªã£ããããã¿ããªé¢åãããã¨æãã¤ã¤æ¯åã³ããããããããã¾ããã§ããã
Orbsã¯åå©ç¨å¯è½ãªãã¼ããæä¾ã§ããä»çµã¿ã§ãããèªåã§ä½ããã¨ã誰ããä½ã£ãOrbsã使ããã¦ããããã¨ã§ã³ããã³ã¼ããæ¸ãããã¨ãã§ãã¾ãã
Orbsãç¥ã
npm install
ã®ãã£ãã·ã¥å¨ãã ããOrbsã§è§£æ±ºããæ¹æ³ãæ¤ç´¢ãã¦è¨äºã«è¾¿ãçããæ¹ã¯å
ç¨ã®ãµã³ãã«ã³ã¼ãã ãã§ååããããã¾ããã
ããããã¯Orbsã使ãããã«ç¥ã£ã¦ããã¹ãè¦ç´ ã解説ãã¾ãã
Orbsã¯Commands, Executors, Jobsã§æ§æããã¦ãã¾ãã3ã¤ãå
¨ã¦å«ãå¿
è¦ã¯ãªããCommandsã ãã§æ§æããã¦ããOrbsãããããããã¾ããã§ã¯å®éã«ããã¥ã¡ã³ããè¦ãªããããããã«ã¤ãã¦ç解ãã¦ããã¾ãããã
https://circleci.com/docs/2.0/using-orbs/
Commands
Commandã¯stepsã®éã¾ãã§ããããã¦stepsã¯run
ã¨ãsave_cache
ãªã©ã®ãã¨ã§ãã
workflowsã§è¤æ°ã®jobã«åå²ãã¦ããã¨åãã³ãã³ãã®ã³ããã ããã«ãªããã¨ãå¤ãã§ãããåãã³ãã³ããç¹°ãè¿ãã¦ããå ´åã¯ä¸é£ã®æµããCommandã¨ãã¦ç»é²ããã¦ããOrbsã使ããã¨ã§ã³ããã³ã¼ããæ²æ»
ã§ãã¾ãã
Orbsã®ä¸ã«ã¯ãã©ã¡ã¼ã¿ãåãåããæåãå¤ãããã¨ãã§ãããã®ãåå¨ãã¾ããä¾ãã°ãå
ç¨ã®ãµã³ãã«ã®with-cache
ã§ã¯dir
, cache-version
, steps
ããã©ã¡ã¼ã¿ã§ãã
ã¡ãªã¿ã«Commandã®ä¸ã«stepsãå
¥ãåã«ãããã¨ãå¯è½ã§ãwith-cache
ã¯ããããã¾ãæ´»ç¨ãããã®ã¨ãªã£ã¦ãã¾ãã詳ããã¯å¾è¿°ãã¾ãã
Jobs
Commandã¨Executorãä¸ç·ã«ãªã£ããã®ãJobã§ããå®ã¯ããã¯è¦æ £ãããã®ã§ããã2.0ããæèããã¨ãå®ç¾©ãã¦ããjobsã®ä¸ã§å®è¡ç°å¢ã®dockerã¤ã¡ã¼ã¸ã¨stepsãæ¸ãã¦ããã¯ãã§ãã
workflowsã§jobsã«å®ç¾©ãããã®ã使ç¨ãã¦ããã®ã¨åãããã«ãã¦ãOrbsã§å®ç¾©ãããjobsãã¾ãworkflowsã®ä¸ã§ä½¿ããã¨ãå¯è½ã§ãã
Executors
è¦æ £ããªãåèªã§ãããããå®ã¯æ°ããæ¦å¿µã¨ããããã§ã¯ããã¾ãããä»ã¾ã§jobsã®ä¸ã§dockerã¤ã¡ã¼ã¸ãæå®ãã¦ãããã®ãExecutorã§ãã
å人çã«ã¯Executorã¯å®ã¯Orbsã®ä¸ã§çµæ§éè¦ãªãã®ã§ã¯ãªããã¨æãã¾ããåºæ¬çã³ããã³ã¼ããæ²æ» ããããã«Orbsã使ããã¨ãå¤ãã¨æãã¾ãããOrbsã®ä¸ã§å®ç¾©ããã¦ããCommandãå®è¡ã§ãããã©ããã¯å®è¡ç°å¢ã«ä¾åãã¦ãã¾ãã
ä¾ãã°ãnpm
ã¯nodejsãåãç°å¢ã§ãã使ãã¾ããããbundler
ã¯rubyãåãç°å¢ã§ãã使ãã¾ãããnpm
ãbundler
ã§ããã°Docker Hubããå
¬å¼ã®ã¤ã¡ã¼ã¸ãæ¢ãã°OKã§ãããããä¾ã¨ãã¦Herokuã«ä½¿ç¨ããheroku
ã³ãã³ããæ±ãOrbsãè¦ã¤ããã¨ãã¦ããã®å®è¡ç°å¢ã«ã¯ã©ã®dockerã¤ã¡ã¼ã¸ã使ãã¹ãã§ããããï¼
ãã®ããã«ãå®ã¯Commandã ãã§ã¯çæè½ã¡ãªã®ã§ããExecutorãç¨æããã¦ããOrbsã§ã¯ä½è ãCommandã®å®è¡ã«å¿ è¦ãªç°å¢ãæå®ãã¦ããã¯ãã§ãã®ã§ãOrbsãæä¾ãã¦ããExecutorãæå®ããã°å®è¡ç°å¢ã«ã¤ãã¦èããå¿ è¦ã¯ãªããªãã§ãããã
ã¾ããOrbsã対å¿ãã¦ããã°Executorã«ããã©ã¡ã¼ã¿ã渡ããã¨ãå¯è½ã§ãããã©ã¡ã¼ã¿ãdockerã¤ã¡ã¼ã¸ã®ã¿ã°æå®ã«ä½¿ããã¨ã§ãè¨èªãOSã®ãã¼ã¸ã§ã³ãããç¨åº¦ã³ã³ããã¼ã«å¯è½ã«ãã¦ãããã®ãå¤ãããã§ãã
å®éã«å¤é¨è£½ã®Orbsã®ããã¥ã¡ã³ããèªãã§ã¿ãã
ã§ã¯å®éã«circleci/node使ãæ¹ãããã¥ã¡ã³ãããèªã¿è§£ãã¦ã¿ã¾ãããã
Commands
å·çæç¹ã§ã®ãã¼ã¸ã§ã³0.0.8ã§ã¯Commandsã3ã¤ããã¾ããããµã³ãã«ã§ã使ç¨ããwith-cache
ãä¾ã«è§£èª¬ãã¾ãã
ã¾ããsteps
ãREQUIREDã«ãªã£ã¦ããããããã®ãã©ã¡ã¼ã¿ã¯å¿
é ã§ãããã¨ãåããã¾ããããã¦ãDESCRIPTIONã«ããã¨ãNodeã®ãã£ãã·ã¥ã使ããªããå®è¡ããã¹ããããæå®ããããã§ãã
次ã«dir
, cache-key
, cache-version
ãè¦ãã¨ãããã©ã«ãå¤ããããã以ä¸ã®ããã«ãªã£ã¦ãã¾ãã
PARAMETER | DEFAULT |
---|---|
dir | ~/project/node_modules |
cache-key | package.json |
cache-version | v1 |
ã¡ãªã¿ã«ãOrbsã使ãåã®config.ymlã§ã¯save_cache
ã¹ãããã¯ãã®ããã«ãã¦ãã¾ãããããããè¦ãã¨ããããã®ãã©ã¡ã¼ã¿ã¯ããããsave_cache
ã®ã¹ãããã§ä½¿ç¨ããå¤æ°ãã³ã³ããã¼ã«ãããã®ã ã¨æ¨æ¸¬ãã§ãã¾ãã
- save_cache: paths: - node_modules key: v1-dependencies-{{ checksum "package.json" }}
ã§ã¯æ¬å½ã«æ³å®ããæåãã©ããã確èªãã¾ãã"Show Command Source"ã¨æ¸ããã¦ãããªã³ã¯ãã¯ãªãã¯ããã¨Orbsã®å®éã®yamlã表示ãããã®ã§è¦ã¦ã¿ã¾ãããã
ã¾ããç´°ãããã©ã¡ã¼ã¿ãçç¥ããã¨å
¨ä½ã®æµãã¯ãã®ããã«ãªã£ã¦ãã¾ãã
steps: - when: condition: << parameters.use-strict-cache >> steps: - restore_cache: - unless: condition: << parameters.use-strict-cache >> steps: - restore_cache: - steps: << parameters.steps >> - save_cache:
use-strict-cache
ã®when-unlessãä¸æ¦æ¨ªã«ããã¦ããã¨ãrestore_cache
-> ä»»æã®steps -> save_cache
ã¨ããæµãã«ãªã£ã¦ãããã¨ãåããã¾ããã¤ã¾ããsteps
ãã©ã¡ã¼ã¿ã«ãã£ãã·ã¥å¨ã以å¤ã®npm install
ãnpm run build
ã¨ãã£ãstepã渡ãã°ããæãã«ãã£ãã·ã¥ãæ±ã£ã¦ãããããªæãããã¾ãã
次ã«save_cache
ã®å®ç¾©ãè¦ã¦ã¿ã¾ããããkeysã®æååãèªã¿è§£ãã¨ãcache-version
, ãã©ã³ã, cache-key
ã®ãã§ãã¯ãµã ã®3ã¤ã®çµã¿åããã§ãã£ãã·ã¥ãå¤å®ããdir
ã®ãã£ã¬ã¯ããªããã£ãã·ã¥å¯¾è±¡ã¨ãããã¨ãåããã¾ãã
- save_cache: key: >- node-deps-<< parameters.cache-version >>-{{ .Branch }}-{{ checksum "<< parameters.cache-key >>" }} paths: - << parameters.dir >>
ã©ãã§ããããããã£ã¨è¦ãã ãã§ãwith-cache
ãã©ã®ãããªæåãããã®ã大ä½ã¤ãããã®ã§ã¯ãªããã¨æãã¾ãã
Executors
ãã¼ã¸ã§ã³0.0.8ã«ã¯Executorã4種é¡ããã¾ããããããdefault
ãæ¨æºã¨ãã¦ç¨æããã¦ãããã®ãªã®ã§ãã¡ãã解説ã¨ããããã¨ããã§ãããå®éã«ã³ã¼ããè¦ã¦ã¿ãã¨node
ã¨å
¨ãåä¸ãªã®ã§node
ãä¾ã«ãã¾ãã
"Show Executor Source"ãã¯ãªãã¯ããã¨ä»¥ä¸ã®å®éã®ã³ã¼ãã表示ããã¾ããé常ã«ã·ã³ãã«ã«ãªã£ã¦ãããdockerã¤ã¡ã¼ã¸ã«ã¯circleci/node
ã使ç¨ããã¿ã°ã®æå®ãtag
ãã©ã¡ã¼ã¿ã§å¯è½ãªãã¨ãåããã¾ãã
ããã©ã«ãå¤ã¯latest
ã§ããã¤ã¾ããèªåã®config.ymlä¸ã§ãã®Orbsã®Executorã使ç¨ããã¨ãå®éã«ã¯circleci/nodeã®dockerã¤ã¡ã¼ã¸ã使ç¨ãããã¨ãããã¨ãåããã¾ãã
parameters: tag: type: string description: Pick a specific circleci/node image variant. default: latest docker: - image: 'circleci/node:<< parameters.tag >>
ããã¾ã§ããã¥ã¡ã³ãããèªã¿è§£ããæåãå ã«ãåã³æåã«ç¤ºããOrbsã使ç¨ãããµã³ãã«ã³ã¼ããè¦ç´ãã¦ã¿ã¦ãã ãããOrbsã®æ¦å¿µãããã¦ä½¿ãæ¹ãããã»ã©é£ãããã®ã§ã¯ãªããã¨ãåãããã¨æãã¾ãã
çç³æ··äº¤ã®Orbsã®ä¸ããçãæ¢ãæ¹æ³
ããã¾ã§ã®è§£èª¬ã«ãã£ã¦èªåã§Orbsãä½ããã¨ããå¤é¨è£½ã®Orbsãæ´»ç¨ããæ¹æ³ãç解ã§ããã¨æãã¾ãã
次ã¯å®éã«å¿
è¦ãªOrbsãæ¢ããã¨ã«ãªãã®ã§ãããä»ã¯Orbsãå
¬éãããã°ããã¨ãããã¨ããã£ã¦å°ãè¦ãã ãã§ã以ä¸ã®ããã«çç³æ··äº¤ã®ç¶æ³ã§ãã
- CircleCI謹製
- ããªãæ¬æ°ã§ä½æããã³ãã¥ããã£è£½
- ã¨ãããããã£ã¦ã¿ã¾ããã¬ãã«
èªåã使ãããã³ãã³ãã§æ¤ç´¢ãã¦åè£ãè¤æ°åå¨ããå ´åãããã¾ã§ç§è¦ã§ãã以ä¸ã®ç¹ã§åªãã¦ãããã®ãé¸ã¶ã¨è¯ãã¨æãã¾ãã
æå®å¯è½ãªãã©ã¡ã¼ã¿ãå¤ããã®
ãã©ã¡ã¼ã¿ãå¤ã = æåãç´°ããã³ã³ããã¼ã«ã§ããã¨ãããã¨ã
èªåã使ãããã³ãã³ãã®ãªãã·ã§ã³ãã³ã³ããã¼ã«ã§ãããã©ã¡ã¼ã¿ãåå¨ããªãå ´åãOrbsã使ããªããã¨ã«ãªã£ã¦ãã¾ãã¾ããæåããæãç´°ããæåãªã©ãããã®ãªãã°ã¡ããã¨Orbsã®ã³ã¼ãã確èªãã¦ããã¾ãããã
ä¾ãã°ãwith-cache
ã¯ãã©ã¡ã¼ã¿ã®æ°ãè±å¯ã ã£ãã®ã§ãã£ãã·ã¥å¨ãã§å°ããã¨ã¯ãªãããã§ããã
Orbsãå©ç¨ãããã¨ã§ã³ã¼ãéã®æ¸å°ãè¦è¾¼ãããã®
ä¾ã¨ãã¦ç´¹ä»ããwith-cache
ã¯Commandã«stepsã渡ããã¨ããä»æ§ããã¾ãæ´»ç¨ãããã¨ã§restore_cache
, save_cache
ã®ã³ã¼ããæ¸ããã¦ãã¾ããããã«ããã£ãã·ã¥ã¨ããæ¬æ¥ãã¾ãæ°ã«ãããã¯ãªãå·¥ç¨ãé è½ãã¦ãããç¹ã§é常ã«åªãã¦ããã¨æãã¾ãã
ä»ã«ã¯ããã©ã¡ã¼ã¿ã®ããã©ã«ãå¤ã¨ãã¦å¦¥å½ãªãã®ãè¨å®ããã¦ãããã©ãããéè¦ã§ãããããã©ã¡ã¼ã¿ã®æ°ã¯å¤ãã»ããè¯ãã¨å è¿°ãã¾ããããããã©ã«ãå¤ãå¾®å¦ã ã¨èªåã§å ¨ã¦æå®ãããã¨ã«ãªã£ã¦ãã¾ãã¾ãã
executorã¨ãªãdockerã¤ã¡ã¼ã¸ã®ã¿ã°ãæè»ã«é¸æå¯è½ãªãã®
ä¾ãã°ãexecutorã§æå®ãããdockerã¤ã¡ã¼ã¸ãcircleci/node:10
ã¨ã¿ã°ãåºå®ããã¦ãã¾ã£ã¦ããå ´åãã©ããªãã§ããããï¼
ãã®å ´åãæ°ããNode.jsã®ãã¼ã¸ã§ã³ãå°æ¥å
¬éãããã¨ãã¦ããcircleci/node:11
ãæå®ã§ããªãããå¤ãNode.jsã使ç¨ãç¶ãããããªããªã£ã¦ãã¾ãã¾ãã
ãã®Orbsã®ãã¼ã¸ã§ã³ãä¸ãããã¨ã§Executorsãæ´æ°ããã¦æ°ããNode.jsã«å¯¾å¿ããå¯è½æ§ãããã¾ããããã®å ´åã¯Executors以å¤ã«JobsãCommandsã«éäºæã§ç ´å£çãªå¤æ´ãå ¥ãå¯è½æ§ãæãå¾ãã§ãããã
Executorã®ãã©ã¡ã¼ã¿ã使ã£ã¦ããç¨åº¦æè»ã«dockerã¤ã¡ã¼ã¸ãæå®ã§ããOrbsã§ããã°ãOrbsã®ãã¼ã¸ã§ã³ãåºå®ãã¦ããã©ã¡ã¼ã¿ãæ´æ°ããã ãã§æ°ããdockerã¤ã¡ã¼ã¸ã使ããã¨ãã§ãã¾ãã
ã¾ã¨ã
CircleCI 2.1ããç»å ´ããOrbsã¯ã¾ã ãµã³ãã«ã³ã¼ãããã¾ããªãç¶æ³ã§ãããã®ãããªç¶æ³ã§ãã®ã§ããã¥ã¡ã³ããè¦ãã ãã§ä½¿ãæ¹ãèªã¿è§£ããããã«Orbsã®ä½¿ãæ¹ã解説ãã¾ããã
ãã®è¨äºã§Orbsã®æ¦å¿µã¨ããã¥ã¡ã³ãã®èªã¿æ¹ã¯ç解ã§ããã¨æãã¾ãã®ã§ããã²Orbsã®ããã¥ã¡ã³ããã³ã¼ããèªã¿è§£ããªããæ´»ç¨ãã¦ã¿ã¦ãã ããã
Firestoreããã£ã¨æ軽ã«ä½¿ããfirestore-simpleããã¼ã¸ã§ã³2ã«ãªãã¾ãã
追è¨: v4ã«ã¤ãã¦ã®ã¨ã³ããªã¯ãã¡ã
ãã®è¨äºã¯Firebase Advent Calendar 2018 3æ¥ç®ã®è¨äºã§ã
ä»å¹´ã®6æã«firestore-simpleã¨ããjsããFirestoreã使ãã¨ãã«ä½¿ããããããã¢ã¸ã¥ã¼ã«ããªãªã¼ã¹ãã¦ãã¾ããã
Firestoreããã£ã¨æ軽ã«ä½¿ããfirestore-simpleãä½ã£ã
GitHub - Kesin11/Firestore-simple: A simple wrapper for Firestore
ãªãªã¼ã¹å¾ãèªåã®è¶£å³ããã¸ã§ã¯ãã§ä½¿ãç¶ãã¦ããã®ã§ãããTypeScriptã®åä»ããä¸éå端ã§æãããä»ã²ã¨ã¤ä½¿ãã«ããæãã§ãããããã§TypeScriptã®åã«ã¤ãã¦ã¡ããã¨åå¼·ããã¦ãGenericsãªã©ãæ´»ç¨ãã¦ãã£ã¨ããæãã«åãæ±ããããã«æ¹è¯ãããã¼ã¸ã§ã³2ããªãªã¼ã¹ãã¾ããã ð
ãµã³ãã«ã³ã¼ãã¯ãããªæãã§ãããã²Firestoreã®ããã¥ã¡ã³ãã¨è¦æ¯ã¹ã¦ã¿ã¦ãã ãããç´ ã®Firestoreãããããªãã·ã³ãã«ãªã³ã¼ãã§æ¸ãããã¨ãåããã¨æãã¾ãã
# install
$ npm i firestore-simple
// 以ä¸ã®ã³ã¼ãã¯TypeScriptã§ã const firestore = admin.firestore() firestore.settings({ timestampsInSnapshots: true }) interface User { id: string, name: string, age: number, } const main = async () => { // Firestoreãããã§ããããã¨ãã«ãããã³ã°ãããåãGenericsã«æå®ãã // pathã¯Firestoreã®ã³ã¬ã¯ã·ã§ã³ãã¹ const dao = new FirestoreSimple<User>({ firestore, path: 'user' }) // addã®æ»ãå¤ã¯Firestoreã«ãã£ã¦ä»ä¸ãããidãå«ãUserå const user: User = await dao.add({ name: 'bob', age: 20 }) console.log(user) // { name: 'bob', age: 20, id: '3Y5jwT8pB4cMqS1n3maj' } // fetchã®æ»ãå¤ã®å㯠User | undefined let bob: User | undefined = await dao.fetch(user.id) console.log(bob) // { id: '3Y5jwT8pB4cMqS1n3maj', age: 20, name: 'bob' } if (!bob) return // update bob.age = 30 bob = await dao.set(bob) // add or set // idãããã°setããªããã°add let alice: User = await dao.addOrSet({ name: 'alice', age: 22 }) console.log(alice) // { name: 'alice', age: 22, id: 'YdfB2rkXoid603nKRX65' } alice.age = 30 alice = await dao.addOrSet(alice) console.log(alice) // { name: 'alice', age: 30, id: 'YdfB2rkXoid603nKRX65' } // delete const deletedId = await dao.delete(bob.id) console.log(deletedId) // 3Y5jwT8pB4cMqS1n3maj await dao.delete(alice.id) // `buldSet`ã¨`bulkDelete`ã¯WriteBatchã使ããããããã©ããã¼ const _bulkSetBatch = await dao.bulkSet([ { id: '1', name: 'foo', age: 1 }, { id: '2', name: 'bar', age: 2 }, ]) // ã³ã¬ã¯ã·ã§ã³ã«å«ã¾ãããã¼ã¿ãå ¨ã¦fetch const users: User[] = await dao.fetchAll() console.log(users) // [ // { id: '1', name: 'foo', age: 1 }, // { id: '2', age: 2, name: 'bar' }, // ] // fetch by query const fetchedByQueryUser: User[] = await dao.where('age', '>=', 1) .orderBy('age') .limit(1) .get() console.log(fetchedByQueryUser) // [ { id: '1', name: 'foo', age: 1 } ] // multi delete const _deletedDocBatch = await dao.bulkDelete(users.map((user) => user.id)) } main()
ã³ã³ã»ãã
firestore-simpleã®ã³ã³ã»ããã¯Firestoreãããjsãããæ±ããããããã¨ãããã®ã§ãã
ããããä½ã£ãåæ©ã¯ãç´ ã®Firestoreã®APIã¯åã«getãsetããã ãã®åç´ãªç¨éã§ãã£ã¦ããjsãã使ãã¥ããã¨ããããã£ãããã§ããæ¯åã©ããã¼ãæ¸ããã¨ã«ãªãããã ã¨æã£ãã®ã§ããªãã°æåã«ã·ã³ãã«ãªAPIã§æ±ç¨çã«ä½¿ãããã®ãä½ããã¨æãã¾ããã ãã®ãããã®è©³ããå 容ã¯ãã¼ã¸ã§ã³1ããªãªã¼ã¹ããã¨ãã®ã¨ã³ããªãè¦ã¦ããããã°ã¨æãã¾ãã
競åã¨ã®æ¯è¼
競åã¨ãã¦ãvue-firestoreããpring.tsãªã©ãæ¢ã«ããã¾ãã
vue-firestoreã¯ç¹å®ã®ã©ã¤ãã©ãªã¨å¯çµåãã¦ããã®ãå人çã«ã¯å¥½ã¿ã§ã¯ãªãã®ã¨ãCloud Functionsã®ãããªVue.jsã®å¤ã®ä¸çã§ã¯çµå±ä½¿ããªãã¨ãããèªåã®ãã¼ãºã¨åãã¾ããã§ããã
pring.tsã¯ãµã³ãã«ã³ã¼ããè¦ãæãã§ã¯APIãç°¡æ½ã§èªåãããããã£ããã¨ã«è¿ãã£ãã®ã§ãããæåã«ã¯ã©ã¹ã®ä¸ã§ã¢ããã¼ã·ã§ã³ãä»ãã¦ããããã£ãå®ç¾©ããæ¹æ³ãSwiftãJavaã£ã½ãã¦èªåã®jsæã¨ããããã¾ããã§ããã
firestore-simpleã¯Firestoreã®èãã©ããã¼ã§ãããã¡ã¤ã³ã®æ©è½ã¯Firestoreããåå¾ããããã¥ã¡ã³ããjsã®ãã¬ã¼ã³ãªãªãã¸ã§ã¯ãã«ããã ãã§ãããã®ã¾ã¾ä½¿ã£ã¦ã便å©ã§ãããããããModelãRepositoryã«çµã¿è¾¼ãã§çã®Firestoreã®ä»£ããã«ä½¿ãã®ã便å©ã ã¨æãã¾ããèªåã®ããã«ççµåãªã¯ã©ã¹è¨è¨ãããã人åãã ã¨æãã¾ãã
ä»ã®ã©ã¤ãã©ãªã¨å¯çµåãã¦ããªãããããã©ã¦ã¶ä¸ã®jsããFirestoreã使ãå ´åãnodejsã®Admin SDKãCloud Functionsã®ãããã§ãå©ç¨å¯è½ã§ãã
ãã¼ã¸ã§ã³2ã§å¤§ããå¤ãã£ããã¤ã³ã
Genericsãæ´»ç¨ãã¦åãæ±ããããããã¨ããããã¼ã¸ã§ã³2ã®ç®çã®å¤æ´ç¹ã§ãããããã«å ãã¦APIã®ç ´å£çãªå¤æ´ãå«ããå¤æ´ç¹ãç´¹ä»ãã¾ãã
1. TypeScriptã§Genericsãæ´»ç¨ããåæ å ±ãä»ããããããã«ãªã£ã
TypeScriptããFirestoreã使ãã¨ãã«è¾ãã£ãã®ããFirestoreããfetch
ããã¨ãã«åæ
å ±ãä»ããªããã¨ã§ããããã®ãããfetch
ãããªãã¸ã§ã¯ãã¯å³åº§ã«ã¯ã©ã¹ãã¤ã³ã¿ã¼ãã§ã¼ã¹ã«ãããã³ã°ãã¦åãä»ãã¦ããã®ã§ãããæ¯åæ¸ãã®ã¯ã¨ã¦ãããã©ããããã¨ã§ããã
ãã¼ã¸ã§ã³1ã§ã¯firestore-simpleã使ã£ã¦fetch
ãã¦ããªãã¸ã§ã¯ãã«id
ã¨ããããããã£ãåå¨ãã¦ãããã¨ã ããä¿è¨¼ããã¨ããä¸éå端ãªåæ
å ±ãããªãã£ãã®ã§ããããã¼ã¸ã§ã³2ã§ã¯Genericsãæ´»ç¨ãããã¨ã§fetch
ããã¨ãã«èªåçã«åæ
å ±ãä»ãããã«ãªãã¾ããï¼
interface User { id: string, name: string, age: number, } const dao = new FirestoreSimple<User>({ firestore, path: 'user' }) // æ»ãå¤ã¯Userå const user = await dao.fetch('bob')
Firestoreããfetch
ããçµæãã¯ã©ã¹ã«ãããã³ã°ãããåã«ãªãã¸ã§ã¯ãã«åã欲ããã ãã§ããã°ããã ãã§ããã¤ã³ã¿ã¼ãã§ã¼ã¹ã®åãGenericsã§æå®ããã ãã§æ¸ã¿ãç°¡æ½ã«æ¸ããã¨ãã§ãã¾ãã
2. Firestoreã«ä¿åãFirestoreããåå¾ããã¨ãã®ãããã³ã°å¦çãèªç±ã«æ¸ããããã«ãªã£ã
ãã¼ã¸ã§ã³1ã§ã¯js <-> Firestoreãè¡ãæ¥ããã¨ãã®ããããã£åã®å¤æã«ã¼ã«ï¼created_at <-> createdAtãªã©ï¼ã ãã¯å®ç¾©ãã¦ãããã¨ãã§ãã¾ããããã¼ã¸ã§ã³2ã§ã¯Firestoreã«ä¿åããã¿ã¤ãã³ã°ãencode
, Firestoreããåãåºãã¿ã¤ãã³ã°ãdecode
ã¨ãã¦ãããã«ãããã³ã°ã®å¦çãèªç±ã«æ¸ããããã«ãªãã¾ããã
class Book { public id: string public title: string public created: Date constructor ({ title, created }: { title: string, created: Date }) { this.id = title this.title = title this.created = created } } const dao = new FirestoreSimple<Book>({ firestore, path: 'user', // Firestoreã«add, setããã¿ã¤ãã³ã°ã§å¼ã°ãã // æ»ãå¤ã®ãªãã¸ã§ã¯ãã®ããããã£ã§Firestoreã«ä¿åããã encode: (book) => { return { id: book.id, book_title: book.title, // Firestoreã§ã¯book_titleã¨ããããããã£åã«ãªã created: book.created, } }, // Firestoreããfetchããã¿ã¤ãã³ã°ã§å¼ã°ãã // decodeã®æ»ãå¤ã®åã¯Genericsã¨ä¸è´ãã¦ããå¿ è¦ããã decode: (doc) => { return new Book({ // Firestoreä¸ã§ã¯book_titleã¨ããããããã£åã ã£ãããBookã§ã¯titleã¨ããããããã£åã«å¤æ title: doc.book_title, // Firestoreã®ä»æ§ä¸ãDateã§ä¿åãã¦ããå¤ã¯fetchããã¨ãã«Firestoreã®Timestampåã«ãªã£ã¦ããã®ã§Dateåã«å¤æ created: doc.created.toDate(), }) }, }) // ãããã³ã°å¦çãencode/decodeã§å®çµããã®ã§å®éã®å¦çãã·ã³ãã«ã«ãªã const book = new Book({ title: 'foobar', created: new Date() }) await dao.set(book) await dao.fetch(book.id)
注æç¹ã¨ãã¦ã¯ãencode
ã®ã¨ãã«idã¯ãªãã·ã§ãã«ã§ãéã«decode
ã®ã¨ãã¯idãå¿
é ã«ãã¦ãããã¨ã§ãã
ããã¯ãadd
ããã¨ãã«ã¯idãå¿
é ã§ã¯ãªãã§ãããéã«fetch
ããã«ã¯idãå¿
é ã§ããããã§ãã
ãã®idã«ã¾ã¤ããåä»ãã¯åããã°ã©ãã³ã°ã§é å¼µã£ã¦å®ç¾ãã¦ããã®ã§ãããã³ã³ãã¤ã«ã¨ã©ã¼ã®ã¨ã©ã¼ã¡ãã»ã¼ã¸ã¯å°ãé·ããªã£ã¦ãã¾ãã¾ããã ããã³ã³ãã¤ã«ã¨ã©ã¼ã«ãªã£ãã¨ãã«ã¯å°ã注ææ·±ãã¨ã©ã¼ã¡ãã»ã¼ã¸ãèªãå¿ è¦ãããããããã¾ããã
3. ãµãã¯ã©ã¹ãã¼ã¹ãªæ¹æ³ããµãã¼ã
ããã¾ã§ã®ãµã³ãã«ã³ã¼ãã§ç¤ºããããã«ãFirestoreSimpleã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹ãä½æããã®ãåºæ¬çãªæ³å®ãã使ãæ¹ã§ãããIndexdDBã®ã©ããã¼ã§ããDexie.jsã®ããã«ãµãã¯ã©ã¹ãä½æãã¦ä½¿ãæ¹æ³ãå¯è½ã«ãã¾ããã
class Book { public id: string public title: string public created: Date constructor ({ title, created }: { title: string, created: Date }) { this.id = title this.title = title this.created = created } } class BookDao extends FirestoreSimple<Book> { constructor ({ firestore }: { firestore: Firestore }) { super({ firestore, path: 'example/ts_admin/book' }) } // override public encode (book: Book) { return { id: book.id, book_title: book.title, created: book.created, } } // override public decode (doc: {id: string, [props: string]: any}) { return new Book({ title: doc.book_title, created: doc.created.toDate(), }) } } const dao = new BookDao({ firestore }) const book = new Book({ title: 'foobar', created: new Date() }) await dao.set(book) await dao.fetch(book.id)
FirestoreSimpleãç¶æ¿ããã¯ã©ã¹ãå®ç¾©ãã¾ããGenericsã®åã¨path
ãåºå®ãããã¨ã§BookDaoã®ã¤ã³ã¹ã¿ã³ã¹ãä½ãã¨ãã«å¼æ°ãã¸ãããã¨ãã§ãã¾ãã
ããã«encode
ãdecode
ã親ã¯ã©ã¹ã§ããFirestoreSimpleã®ã¡ã½ããããªã¼ãã¼ã©ã¤ããã¦ãã¾ããã¨ã§ãã³ã³ã¹ãã©ã¯ã¿ã§æ¸¡ãå¿
è¦ããªããªãã¾ããã
å¾æ¥ã®æ¹æ³ã¨ããµãã¯ã©ã¹ãã¼ã¹ãªæ¹æ³ã§å®ç¾ã§ãããã¨ã«å·®ç°ã¯ããã¾ããã好ã¿ã®æ¹æ³ãé¸æãã¦ãã ããã
æªãµãã¼ããªæ©è½
firestore-simpleã¯ãèªåã®Firestoreã®ä½¿ãæ¹ã«ç¹åãã¦ãã¶ã¤ã³ãã¦ããã¨ãããå¼·ããããæ®å¿µãªããFirestoreã®å ¨ã¦ã®æ©è½ãã¾ã ãµãã¼ããã¦ããããã§ã¯ããã¾ããã
ãªãã¡ã¬ã³ã¹ã¨ãµãã³ã¬ã¯ã·ã§ã³ã®ãµãã¼ãã¯ï¼ä»ã®ã¨ããï¼ç¡ã
firestore-simpleã¯Firestoreããåå¾ããããã¥ã¡ã³ãããã¬ã¼ã³ãªjsã®ãªãã¸ã§ã¯ãã«å¤æãã¦ãã¾ããããæ®å¿µãªãããªãã¡ã¬ã³ã¹ã¨ãµãã³ã¬ã¯ã·ã§ã³ã«ã¤ãã¦ã¯ãµãã¼ããã¦ãã¾ããã
// userã®ãµãã³ã¬ã¯ã·ã§ã³ã«itemsãããã¨ãã /user/:user_id/items/:item_id // ãã®ããã«fetchããuserã®ãµãã³ã¬ã¯ã·ã§ã³ãç°¡åã«è¾¿ããã¨ã¯ã§ããªã const user = await dao.fetch(user_id) const user_items = await user.items.fetchAll()
èªåããªãã¡ã¬ã³ã¹ã¨ãµãã³ã¬ã¯ã·ã§ã³ã使ã£ã¦ããªãããã«ã¾ã ãã®æ©è½ããã¶ã¤ã³ãã¦ããªããã¨ããã®ããµãã¼ãã§ãã¦ããªã主ãªçç±ã§ããèªåã使ãããã«ãªã£ãã¿ã¤ãã³ã°ã§ãµãã¼ãããå¯è½æ§ã¯ããã¨æãã¾ãã
transactionã®ãµãã¼ãã¯ï¼ä»ã®ã¨ããï¼ç¡ã
ãã©ã³ã¶ã¯ã·ã§ã³ãå¿ è¦ãªã®ã¯è¤æ°ã®ã³ã¬ã¯ã·ã§ã³ã«ã¾ããã£ãæä½ãã¢ãããã¯ã«è¡ãããã±ã¼ã¹ã§ããããfirestore-simpleã¯ãã®ã¤ã³ã¹ã¿ã³ã¹ãã¨ã«1ã¤ã®ã³ã¬ã¯ã·ã§ã³ã®æä½ã«ç¹åããããã«ãã¶ã¤ã³ãã¦ãã¾ã£ããããtransactionãããæãã«æ±ãAPIã®ãã¶ã¤ã³ãèãããã¦ãããã¾ã å®è£ ãã¦ãã¾ããã
èªåãFirestoreã使ãéçºã«ããã¦transactionã欲ããã¨æã£ãå ´é¢ã«ç´é¢ãã¦ããªãã®ã§åªå 度ã¯ãã¾ãé«ããªãã®ã§ãããtransactionã¯ç¨éã«ãã£ã¦ã¯å¿ é ã¬ãã«ã ã¨æãã¾ãã®ã§ãã®ãã¡ãµãã¼ãããããªã¨ã¯èãã¦ãã¾ãã
onSnapshotã¯é¨åãµãã¼ã
Firestoreã®ã¦ãªã®1ã¤ã§ããonSnapshotã§ããããããä»ã®ã¡ã½ããã®ããã«çã®Firestoreã®APIãã©ããããã®ã¯ããªã大å¤ããã ã£ãããé¨åãµãã¼ãã¨ãã¦ãã¾ããå®éã«ãµã³ãã«ã³ã¼ããè¦ã¦ãããã®ãæ©ãã§ãããã
dao.where('age', '>=', 20) .onSnapshot((querySnapshot, toObject) => { // querySnapshotã¯Firestoreã®çã®onSnapshot()ã®å¼æ°ã¨åããã® querySnapshot.docChanges.forEach((change) => { if (change.type === 'added') { // toObjectã¯firestore-simpleãæä¾ããããªãã¸ã§ã¯ãã«å¤æããããã®ã¡ã½ãã // changeDocã®åã¯daoãä½ãã¨ãã«æå®ããGenericsã®åã¨åãã«ãªã const changedDoc = toObject(change.doc) } }) })
Firestoreã®ãªã¢ã«ã¿ã¤ã ã¢ãããã¼ãã®ããã¥ã¡ã³ãã¨æ¯è¼ãã¦ãããã¨ãtoObject
ãã³ã¼ã«ããã¯ã®å¼æ°ã«å¢ããã ãã¨ããã®ãåããã¨æãã¾ãã
toObject
ã¯ãfirestore-simpleãçã®Firestoreããfetch
ããããã¥ã¡ã³ãããªãã¸ã§ã¯ãã«å¤æãããå
é¨ã§ä½¿ç¨ãã¦ããã®ã¨åãã¡ã½ããã§ããonSnapshotã®å¦çã®ä¸ã§toObject()
ãéããã¨ã§firestore-simpleã®ä»ã®ã¡ã½ããã®æ»ãå¤ã¨åãåã«ã§ãã¾ãã
ä»ã®APIã®ããã«çã®Firestoreããã使ãåæãããã»ã©è¯ããªãããã§ã¯ãªãã§ãããå®ç¨ä¸ã¯ããã»ã©åé¡ãªãããªã¨æãã¾ãã
ã¾ã¨ã
Firestoreã便å©ã«ãããã¦ã·ã³ãã«ã«js/tsãã使ãããã®firestore-simpleãç´¹ä»ãã¾ããã
æªãµãã¼ããªæ©è½ã®ç¯ã§ç´¹ä»ããããã«ãèªåã®Firestoreã®ä½¿ãæ¹ã«ç¹åãã¦ãã¶ã¤ã³ãã¦ããããä»ã®ã¨ããã¯ã¦ã¼ã¹ã±ã¼ã¹ãéããã¦ãã¾ãããããã¾ããã
ä¸æ¹ã§ãfirestore-simpleã¯é常ã«å°ããªã©ã¤ãã©ãªã§ãæ¬ä½ã®ã³ã¼ãã¯ã¾ã 200è¡ç¨åº¦ããããã¾ãããå¿
è¦ã§ããã°ä¸èº«ã®ã³ã¼ããèªãã§ææ¡ããç¶æ¿ãã¦ç¬èªã«æ¡å¼µãã¦ããããã¨ã容æã ã¨æãã¾ãã
ã¾ã ã¾ã çºå±éä¸ãªã¨ãããå¤ãã§ããããµã³ãã«ã³ã¼ããè¦ã¦ãããããï¼ã¨æã£ãæ¹ã¯ãã²GitHubã®ã¹ã¿ã¼ããpull-reqãé ããã¨å¬ããã§ãï¼