<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yuta Goto</title>
    <description>The latest articles on DEV Community by Yuta Goto (@yutagoto).</description>
    <link>https://dev.to/yutagoto</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F43436%2Ff3e254d5-74cf-4d61-a093-3d121f9e9b38.png</url>
      <title>DEV Community: Yuta Goto</title>
      <link>https://dev.to/yutagoto</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yutagoto"/>
    <language>en</language>
    <item>
      <title>Rubyでディレクトリ操作をする</title>
      <dc:creator>Yuta Goto</dc:creator>
      <pubDate>Wed, 13 Dec 2023 15:01:00 +0000</pubDate>
      <link>https://dev.to/yutagoto/rubydedeirekutoricao-zuo-wosuru-52a6</link>
      <guid>https://dev.to/yutagoto/rubydedeirekutoricao-zuo-wosuru-52a6</guid>
      <description>&lt;p&gt;これは &lt;a href="https://adventar.org/calendars/9122"&gt;.ごっ！のアドベントカレンダー&lt;/a&gt; の14日目の記事です。&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://docs.ruby-lang.org/ja/3.2/class/Dir.html" rel="noopener noreferrer"&gt;
      docs.ruby-lang.org
    &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;rubyのバージョン3.2での情報です。&lt;/p&gt;

&lt;h2&gt;
  
  
  カレントディレクトリのパスを変更
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Dir&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/var/log"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  現在のディレクトリを取得
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Dir&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/tmp"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Dir&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getwd&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "/tmp" &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  カレントディレクトリ配下にあるファイルエントリ取得
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Dir&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;children&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;".circleci"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;".codespellrc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;".gem_rbs_collection"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;".git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;".github"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;".gitignore"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;".rspec"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;".rspec_status"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;".rubocop.yml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;".vscode"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"Gemfile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"Gemfile.lock"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"LICENSE.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"README.md"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"Rakefile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"Steepfile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"bin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"config"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"sample.gemspec"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"lib"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"pkg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"rbs_collection.lock.yaml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"rbs_collection.yaml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"sig"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s2"&gt;"spec"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ruby</category>
      <category>アドベントカレンダー</category>
    </item>
    <item>
      <title>export requirements.txt from Pipfile</title>
      <dc:creator>Yuta Goto</dc:creator>
      <pubDate>Tue, 12 Dec 2023 15:01:00 +0000</pubDate>
      <link>https://dev.to/yutagoto/export-requirementstxt-from-pipfile-3li0</link>
      <guid>https://dev.to/yutagoto/export-requirementstxt-from-pipfile-3li0</guid>
      <description>&lt;p&gt;これは &lt;a href="https://adventar.org/calendars/9122"&gt;.ごっ！のアドベントカレンダー&lt;/a&gt; の13日目の記事です。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Pipfile.lock&lt;/code&gt; ファイルから &lt;code&gt;requirements.txt&lt;/code&gt; ファイルを生成する方法は以下のコマンドを実行します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pipenv requirements &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;開発モジュールを含める場合は &lt;code&gt;--dev&lt;/code&gt; オプションも付けます。&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pipenv requirements &lt;span class="nt"&gt;--dev&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://pipenv.pypa.io/en/latest/pipfile.html#pipfile-lock-security-features" rel="noopener noreferrer"&gt;
      pipenv.pypa.io
    &lt;/a&gt;
&lt;/div&gt;



</description>
      <category>python</category>
      <category>pipenv</category>
      <category>アドベントカレンダー</category>
    </item>
    <item>
      <title>WSL2にGoogle Chromeをインストールする</title>
      <dc:creator>Yuta Goto</dc:creator>
      <pubDate>Mon, 11 Dec 2023 15:01:00 +0000</pubDate>
      <link>https://dev.to/yutagoto/wsl2nigoogle-chromewoinsutorusuru-lij</link>
      <guid>https://dev.to/yutagoto/wsl2nigoogle-chromewoinsutorusuru-lij</guid>
      <description>&lt;p&gt;これは &lt;a href="https://adventar.org/calendars/9122"&gt;.ごっ！のアドベントカレンダー&lt;/a&gt; の12日目の記事です。&lt;/p&gt;

&lt;p&gt;Microsoftのドキュメントの通りの通りに進めます。&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://learn.microsoft.com/ja-jp/windows/wsl/tutorials/gui-apps" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--iMpGPUDN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://learn.microsoft.com/en-us/media/open-graph-image.png" height="420" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://learn.microsoft.com/ja-jp/windows/wsl/tutorials/gui-apps" rel="noopener noreferrer" class="c-link"&gt;
          WSL で Linux GUI アプリを実行する | Microsoft Learn
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          WSL で Linux GUI アプリの実行がどのようにサポートされるかについて説明します。
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
        learn.microsoft.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;前提としてWSL2が有効になっていることとします。&lt;/p&gt;

&lt;h2&gt;
  
  
  インストール
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /tmp
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;dpkg &lt;span class="nt"&gt;-i&lt;/span&gt; google-chrome-stable_current_amd64.deb &lt;span class="c"&gt;# 安定したバージョンを取得&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--fix-broken&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="c"&gt;# パッケージを修正&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;dpkg &lt;span class="nt"&gt;-i&lt;/span&gt; google-chrome-stable_current_amd64.deb &lt;span class="c"&gt;# パッケージを構成&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;google-chrome &lt;span class="nt"&gt;--version&lt;/span&gt;
Google Chrome 119.0.6045.159
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;起動するときは &lt;code&gt;google-chrome&lt;/code&gt; コマンドを実行します。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gnfcZBK9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.esa.io/uploads/production/attachments/10836/2023/12/07/43446/f0192133-ec2d-4adf-bbcb-fbb17d624c90.png" class="article-body-image-wrapper"&gt;&lt;img alt="image.png (564.9 kB)" src="https://res.cloudinary.com/practicaldev/image/fetch/s--gnfcZBK9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.esa.io/uploads/production/attachments/10836/2023/12/07/43446/f0192133-ec2d-4adf-bbcb-fbb17d624c90.png" width="800" height="727"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  アップデート
&lt;/h2&gt;

&lt;p&gt;一度削除してから、再度 &lt;code&gt;wget&lt;/code&gt; で取得してインストールを実行します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nt"&gt;--purge&lt;/span&gt; remove google-chrome-stable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>googlechrome</category>
      <category>wsl2</category>
      <category>アドベントカレンダー</category>
    </item>
    <item>
      <title>lsコマンドで得られたファイル・ディレクトリ名だけを行区切りで表示する</title>
      <dc:creator>Yuta Goto</dc:creator>
      <pubDate>Sun, 10 Dec 2023 15:01:00 +0000</pubDate>
      <link>https://dev.to/yutagoto/lskomandodede-raretahuairudeirekutoriming-dakewoxing-qu-qie-ridebiao-shi-suru-1la7</link>
      <guid>https://dev.to/yutagoto/lskomandodede-raretahuairudeirekutoriming-dakewoxing-qu-qie-ridebiao-shi-suru-1la7</guid>
      <description>&lt;p&gt;これは &lt;a href="https://adventar.org/calendars/9122"&gt;.ごっ！のアドベントカレンダー&lt;/a&gt; の11日目の記事です。&lt;/p&gt;

&lt;p&gt;表題の通り、lsコマンドで得られるファイルやディレクトリ名だけを改行区切りで表示するためには &lt;code&gt;-1&lt;/code&gt; オプションをつけます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/ &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
bin -&amp;gt; usr/bin
boot
dev
Docker
etc
home
init
lost+found
media
mnt
opt
proc
root
run
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;--help&lt;/span&gt;
List information about the FILEs &lt;span class="o"&gt;(&lt;/span&gt;the current directory by default&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Sort entries alphabetically &lt;span class="k"&gt;if &lt;/span&gt;none of &lt;span class="nt"&gt;-cftuvSUX&lt;/span&gt; nor &lt;span class="nt"&gt;--sort&lt;/span&gt; is specified.

Mandatory arguments to long options are mandatory &lt;span class="k"&gt;for &lt;/span&gt;short options too.
  &lt;span class="nt"&gt;-1&lt;/span&gt;                         list one file per line.  Avoid &lt;span class="s1"&gt;'\n'&lt;/span&gt; with &lt;span class="nt"&gt;-q&lt;/span&gt; or &lt;span class="nt"&gt;-b&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://www.tutorialspoint.com/unix_commands/ls.htm" rel="noopener noreferrer"&gt;
      tutorialspoint.com
    &lt;/a&gt;
&lt;/div&gt;



</description>
      <category>unix</category>
      <category>command</category>
      <category>アドベントカレンダー</category>
    </item>
    <item>
      <title>nodenv to pnpm</title>
      <dc:creator>Yuta Goto</dc:creator>
      <pubDate>Wed, 26 Apr 2023 14:28:56 +0000</pubDate>
      <link>https://dev.to/yutagoto/nodenv-to-pnpm-1h9i</link>
      <guid>https://dev.to/yutagoto/nodenv-to-pnpm-1h9i</guid>
      <description>&lt;p&gt;Nodejsの環境の管理を &lt;code&gt;nodenv&lt;/code&gt; から &lt;code&gt;pnpm&lt;/code&gt; に置き換えたので、そのメモです。&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/nodenv" rel="noopener noreferrer"&gt;
        nodenv
      &lt;/a&gt; / &lt;a href="https://github.com/nodenv/nodenv" rel="noopener noreferrer"&gt;
        nodenv
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Manage multiple NodeJS versions.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Seamlessly manage your app’s Node environment with nodenv.&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Use nodenv to pick a Node version for your application and guarantee
that your development environment matches production. Put nodenv to work
with &lt;a href="https://www.npmjs.com/" rel="nofollow noopener noreferrer"&gt;npm&lt;/a&gt; for painless Node upgrades and
bulletproof deployments.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Powerful in development.&lt;/strong&gt; Specify your app's Node version once
in a single file. Keep all your teammates on the same page. No
headaches running apps on different versions of Node. Just Works™
from the command line
Override the Node version anytime: just set an environment variable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rock-solid in production.&lt;/strong&gt; Your application's executables are its
interface with ops. With nodenv and you'll never again need to &lt;code&gt;cd&lt;/code&gt;
in a cron job or Chef recipe to ensure you've selected the right runtime.
The Node version dependency lives in one place—your app—so upgrades and
rollbacks are atomic, even when you switch versions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;One thing well.&lt;/strong&gt; nodenv is concerned solely with switching Node
versions. It's…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/nodenv/nodenv" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://pnpm.io/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpnpm.io%2Fimg%2Fogimage.png" height="auto" class="m-0"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://pnpm.io/" rel="noopener noreferrer" class="c-link"&gt;
          Fast, disk space efficient package manager | pnpm
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Fast, disk space efficient package manager
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpnpm.io%2Fimg%2Ffavicon.png"&gt;
        pnpm.io
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  環境
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;WSL2&lt;/li&gt;
&lt;li&gt;npm v9&lt;/li&gt;
&lt;li&gt;bash&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  nodenvの削除
&lt;/h2&gt;

&lt;p&gt;ホームディレクトリにある &lt;code&gt;.nodenv&lt;/code&gt; を削除します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; ~/.nodenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;.bashrc&lt;/code&gt; に書かれたnodenvの設定を削除します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 以下のような文が書かれているはずです
export PATH="$HOME/.nodenv/bin:$PATH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;.bashrc&lt;/code&gt; を再読み込みし、 nodenvコマンドが使えないことを確認します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt; .bashrc 
&lt;span class="nv"&gt;$ &lt;/span&gt;nodenv
Command &lt;span class="s1"&gt;'nodenv'&lt;/span&gt; not found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  pnpmのインストール
&lt;/h2&gt;

&lt;p&gt;Installationに書いてある通り、wgetでダウンロードしshellを実行します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;wget &lt;span class="nt"&gt;-qO-&lt;/span&gt; https://get.pnpm.io/install.sh | &lt;span class="nv"&gt;ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.bashrc"&lt;/span&gt; &lt;span class="nv"&gt;SHELL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;which bash&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; bash -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;この時点で &lt;code&gt;pnpm&lt;/code&gt; コマンドが使えるはずです。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pnpm &lt;span class="nt"&gt;-v&lt;/span&gt;
8.3.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  nodejsのインストール
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;pnpm use -g&lt;/code&gt; でシステム全体で使用する特定バージョンのnodeのインストールをします。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# v20.X.Xをインストールする&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;pnpm &lt;span class="nb"&gt;env &lt;/span&gt;use &lt;span class="nt"&gt;--global&lt;/span&gt; 20

&lt;span class="c"&gt;# LTS版をインストールする&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;pnpm &lt;span class="nb"&gt;env &lt;/span&gt;use &lt;span class="nt"&gt;--global&lt;/span&gt; lts

&lt;span class="nv"&gt;$ &lt;/span&gt;node &lt;span class="nt"&gt;-v&lt;/span&gt;
v20.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>pnpm</category>
      <category>node</category>
    </item>
    <item>
      <title>Deploy to Google AppEngine with GitHubActions</title>
      <dc:creator>Yuta Goto</dc:creator>
      <pubDate>Mon, 06 Feb 2023 02:55:30 +0000</pubDate>
      <link>https://dev.to/yutagoto/deploy-to-google-appengine-with-githubactions-528i</link>
      <guid>https://dev.to/yutagoto/deploy-to-google-appengine-with-githubactions-528i</guid>
      <description>&lt;p&gt;GitHubActionsを使用してGoogleCloudのAppEngineにデプロイする方法の備忘録です。&lt;/p&gt;

&lt;p&gt;バージョンアップで設定の仕方が変更になっている可能性があるため、最新情報はリポジトリを確認してください。&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/google-github-actions" rel="noopener noreferrer"&gt;
        google-github-actions
      &lt;/a&gt; / &lt;a href="https://github.com/google-github-actions/deploy-appengine" rel="noopener noreferrer"&gt;
        deploy-appengine
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A GitHub Action that deploys source code to Google App Engine.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;deploy-appengine&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;This action deploys your source code to &lt;a href="https://cloud.google.com/appengine" rel="nofollow noopener noreferrer"&gt;App Engine&lt;/a&gt; and makes the URL
available to later build steps via outputs. This allows you to parameterize your
App Engine deployments.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This is not an officially supported Google product, and it is not covered by a
Google Cloud support contract. To report bugs or request features in a Google
Cloud product, please contact &lt;a href="https://cloud.google.com/support" rel="nofollow noopener noreferrer"&gt;Google Cloud
support&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Prerequisites&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This action requires Google Cloud credentials that are authorized to deploy
an App Engine Application. See the &lt;a href="https://github.com/google-github-actions/deploy-appengine#authorization" rel="noopener noreferrer"&gt;Authorization&lt;/a&gt; section
below for more information.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This action runs using Node 20. If you are using self-hosted GitHub Actions
runners, you must use runner version &lt;a href="https://github.com/actions/virtual-environments" rel="noopener noreferrer"&gt;2.285.0&lt;/a&gt;
or newer.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-yaml notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-ent"&gt;jobs&lt;/span&gt;
  &lt;span class="pl-ent"&gt;job_id&lt;/span&gt;:
    &lt;span class="pl-ent"&gt;permissions&lt;/span&gt;:
      &lt;span class="pl-ent"&gt;contents&lt;/span&gt;: &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;read&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt;
      &lt;span class="pl-ent"&gt;id-token&lt;/span&gt;: &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;write&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt;

    &lt;span class="pl-ent"&gt;steps&lt;/span&gt;:
    - &lt;span class="pl-ent"&gt;id&lt;/span&gt;: &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;auth&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt;
      &lt;span class="pl-ent"&gt;uses&lt;/span&gt;: &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;google-github-actions/auth@v2&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt;
      &lt;span class="pl-ent"&gt;with&lt;/span&gt;:
        &lt;span class="pl-ent"&gt;workload_identity_provider&lt;/span&gt;: &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt;
        &lt;span class="pl-ent"&gt;service_account&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/google-github-actions/deploy-appengine" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  サービスアカウントの準備
&lt;/h2&gt;

&lt;p&gt;Google CloudのConsoleメニューのIAMと管理からサービスアカウントにアクセスしアカウントを作成します。App Engineに関するロールは「オーナー」「編集者」「App Engine管理者」「App Engine サービス管理者」のどれかにします。&lt;br&gt;
また、&lt;a href="https://github.com/google-github-actions/deploy-appengine#authorization" rel="noopener noreferrer"&gt;ドキュメント&lt;/a&gt;にもあるとおりに、「ストレージ管理者」「Cloud Build編集者」も付与します。&lt;/p&gt;

&lt;p&gt;作成したサービスアカウントの鍵の作成し、JSONをダウンロードします。&lt;/p&gt;
&lt;h2&gt;
  
  
  Actionの設定
&lt;/h2&gt;

&lt;p&gt;ダウンロードした鍵のJSONの内容をそのまま、GitHub Actionsの環境変数に登録します。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvuxe4ams62pmgu7spirt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvuxe4ams62pmgu7spirt.png" alt="GitHub Actions Secret Variables" width="633" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;準備が整ったら workflowを書いてコミットします。言語ごとのセットアップを適宜書き換えてください。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to App Engine&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GAE Deploy&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;setup nodejs env&lt;/span&gt; &lt;span class="c1"&gt;# 言語に応じて変更する&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;auth'&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Authenticate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Google&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Cloud'&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;google-github-actions/auth@v1'&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;credentials_json&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;secrets.GCP_SA_KEY&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy App&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;google-github-actions/deploy-appengine@v1'&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;project_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GCP_PROJECT_ID }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;問題なく設定できていれば、デプロイが完了します。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjglrnz6otfw626r1zot2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjglrnz6otfw626r1zot2.png" alt="Actions List" width="633" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  躓いた点
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;(gcloud.app.deploy) Your deployment has succeeded, but promoting the new version to default failed. You may not have permissions to change traffic splits. Changing traffic splits requires the Owner, Editor, App Engine Admin, or App Engine Service Admin role. Please contact your project owner and use the "gcloud app services set-traffic --splits &amp;lt;version&amp;gt;=1" command to redirect traffic to your newly deployed version.&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;権限が足りず、デプロイしたバージョンの反映に失敗したエラーです。サービスアカウントの権限をエラー文に書いてある内容のいずれかを付与しrerunすると、このエラーはなくせるはずです。&lt;/p&gt;

</description>
      <category>googlecloudplatform</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>hash keys to method names</title>
      <dc:creator>Yuta Goto</dc:creator>
      <pubDate>Fri, 23 Dec 2022 00:01:00 +0000</pubDate>
      <link>https://dev.to/yutagoto/hash-keys-to-method-names-2ako</link>
      <guid>https://dev.to/yutagoto/hash-keys-to-method-names-2ako</guid>
      <description>&lt;p&gt;これは &lt;a href="https://adventar.org/calendars/8199" rel="noopener noreferrer"&gt;.ごっ！のアドベントカレンダー&lt;/a&gt; の19日目の記事です。&lt;/p&gt;

&lt;p&gt;RubyのHashのキー名をメソッド名として扱うときの備忘録です。&lt;br&gt;
例えば、 &lt;code&gt;h = {num: 42}&lt;/code&gt; があったときに &lt;code&gt;h.num&lt;/code&gt; で&lt;code&gt;42&lt;/code&gt;を取得したいといったときです。&lt;/p&gt;

&lt;p&gt;Rubyの &lt;code&gt;Hash#fetch&lt;/code&gt; と &lt;code&gt;method_missing&lt;/code&gt; をいい具合に利用します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hash&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method_missing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;num: &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;str: &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;first_hash: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;second_hash: &lt;/span&gt;&lt;span class="s2"&gt;"second_hash_str"&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;num&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; 42&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "string"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first_hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;second_hash&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "second_hash_str"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; undefined method 'string' for {....}:Hash (NoMethodError)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;この &lt;code&gt;method_missing()&lt;/code&gt; は &lt;code&gt;Hash&lt;/code&gt;にそのメソッドが定義されていなかった時に呼び出されるメソッドで、引数の &lt;code&gt;m&lt;/code&gt; は呼び出そうとしたメソッド名のSymbolが渡ります。 &lt;/p&gt;

&lt;p&gt;&lt;code&gt;fetch()&lt;/code&gt; はキーに関連付けられた値を返すメソッドです。キーがない場合はブロックの実行結果が返されます。&lt;/p&gt;

&lt;p&gt;それぞれの詳しい内容はリファレンスマニュアルを読んでください。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.ruby-lang.org/ja/3.1/method/BasicObject/i/method_missing.html" rel="noopener noreferrer"&gt;https://docs.ruby-lang.org/ja/3.1/method/BasicObject/i/method_missing.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.ruby-lang.org/ja/3.1/method/Hash/i/fetch.html" rel="noopener noreferrer"&gt;https://docs.ruby-lang.org/ja/3.1/method/Hash/i/fetch.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;上記にあるコードを順番に読み解きます。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;h.num&lt;/code&gt; の場合

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;method_missing&lt;/code&gt; に &lt;code&gt;m = :num&lt;/code&gt; が渡る。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fetch(:num)&lt;/code&gt; で &lt;code&gt;h&lt;/code&gt; には &lt;code&gt;:num&lt;/code&gt; のキーがあるのでその値を返す。

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;h.string&lt;/code&gt; の場合&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;method_missing&lt;/code&gt; に &lt;code&gt;m = :string&lt;/code&gt; が渡る。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fetch(:string)&lt;/code&gt; で &lt;code&gt;h&lt;/code&gt; には &lt;code&gt;:string&lt;/code&gt; のキーが存在しないのでブロックの中身が実行される。&lt;/li&gt;
&lt;li&gt; &lt;code&gt;m.to_s&lt;/code&gt; した結果が &lt;code&gt;fetch&lt;/code&gt; されるので、 &lt;code&gt;fetch("string")&lt;/code&gt;となるが &lt;code&gt;h&lt;/code&gt; には &lt;code&gt;"string"&lt;/code&gt; のキーが存在しないのでブロックの中身が実行される。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;super&lt;/code&gt; で実際の &lt;code&gt;method_missing&lt;/code&gt; が実行される。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;良さげな使い方としては、 APIリクエストしてJSONを受け取った時にメソッドっぽく値を取り出すことができ、きれいなコードを書いているように見えることです。&lt;/p&gt;

&lt;p&gt;以下サンプルコードです。&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'faraday'&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hash&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method_missing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Faraday&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;url: &lt;/span&gt;&lt;span class="s2"&gt;"https://api.nasa.gov"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt; &lt;span class="ss"&gt;:json&lt;/span&gt;
  &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;response&lt;/span&gt; &lt;span class="ss"&gt;:json&lt;/span&gt;
  &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;adapter&lt;/span&gt; &lt;span class="no"&gt;Faraday&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;default_adapter&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"/planetary/apod"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;api_key: &lt;/span&gt;&lt;span class="s2"&gt;"DEMO_KEY"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;copyright&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "Craig Stocks"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "The Tadpole Nebula in Gas and Dust"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;このコードでは  &lt;code&gt;faraday&lt;/code&gt; を使用していますが、httpリクエストの方法はなんでもよいです。&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/lostisland" rel="noopener noreferrer"&gt;
        lostisland
      &lt;/a&gt; / &lt;a href="https://github.com/lostisland/faraday" rel="noopener noreferrer"&gt;
        faraday
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Simple, but flexible HTTP client library, with support for multiple backends.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;&lt;a href="https://lostisland.github.io/faraday" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Flostisland%2Ffaraday.%2Fdocs%2F_media%2Fhome-logo.svg" alt="Faraday"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://rubygems.org/gems/faraday" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ae00e2c6edb17429c06cf9d52b9b1a8bbfb56cab77bb218eb8db3ac39a8028ef/68747470733a2f2f62616467652e667572792e696f2f72622f666172616461792e737667" alt="Gem Version"&gt;&lt;/a&gt;
&lt;a href="https://github.com/lostisland/faraday/actions?query=workflow%3ACI" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/lostisland/faraday/workflows/CI/badge.svg" alt="GitHub Actions CI"&gt;&lt;/a&gt;
&lt;a href="https://github.com/lostisland/faraday/discussions" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/e2bec127cb50218110a6d0fa62266ddbe68c0747c230eafff23a6c340563f3c2/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f64697363757373696f6e732f6c6f737469736c616e642f666172616461793f6c6f676f3d676974687562" alt="GitHub Discussions"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Faraday is an HTTP client library abstraction layer that provides a common interface over many
adapters (such as Net::HTTP) and embraces the concept of Rack middleware when processing the request/response cycle
Take a look at &lt;a href="https://github.com/lostisland/awesome-faraday/#adapters" rel="noopener noreferrer"&gt;Awesome Faraday&lt;/a&gt; for a list of available adapters and middleware.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why use Faraday?&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Faraday gives you the power of Rack middleware for manipulating HTTP requests and responses,
making it easier to build sophisticated API clients or web service libraries that abstract away
the details of how HTTP requests are made.&lt;/p&gt;
&lt;p&gt;Faraday comes with a lot of features out of the box, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Support for multiple adapters (Net::HTTP, Typhoeus, Patron, Excon, HTTPClient, and more)&lt;/li&gt;
&lt;li&gt;Persistent connections (keep-alive)&lt;/li&gt;
&lt;li&gt;Parallel requests&lt;/li&gt;
&lt;li&gt;Automatic response parsing (JSON, XML, YAML)&lt;/li&gt;
&lt;li&gt;Customization of the request/response cycle with middleware&lt;/li&gt;
&lt;li&gt;Support for streaming responses&lt;/li&gt;
&lt;li&gt;Support for uploading files&lt;/li&gt;
&lt;li&gt;And much more!&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting Started&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;The best starting point is the &lt;a href="https://lostisland.github.io/faraday" rel="nofollow noopener noreferrer"&gt;Faraday Website&lt;/a&gt;, with…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/lostisland/faraday" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;レスポンスbodyの中身をまるでメソッドかのように値を取得しています。&lt;/p&gt;




&lt;p&gt;上記のコードは万能ではありません。 &lt;code&gt;Hash&lt;/code&gt; のインスタンスメソッドにあるメソッド名がキー名と同じだった場合、インスタンスメソッドが優先されます。(&lt;code&gt;{dig: "dig_string"}&lt;/code&gt; とあった場合は、&lt;code&gt;method_missing&lt;/code&gt;ではないので  &lt;code&gt;Hash#dig&lt;/code&gt; が優先されるということです。)&lt;/p&gt;

&lt;p&gt;小さい個人ツールやgemとして使う分には便利ではありますが、大きいプロダクトに適用させる場合には注意しましょう。&lt;/p&gt;

</description>
      <category>ruby</category>
    </item>
    <item>
      <title>yarn berryで依存パッケージのバージョンを指定する</title>
      <dc:creator>Yuta Goto</dc:creator>
      <pubDate>Sat, 16 Apr 2022 02:33:02 +0000</pubDate>
      <link>https://dev.to/yutagoto/yarn-berrydeyi-cun-patukezinobaziyonwozhi-ding-suru-3bph</link>
      <guid>https://dev.to/yutagoto/yarn-berrydeyi-cun-patukezinobaziyonwozhi-ding-suru-3bph</guid>
      <description>&lt;p&gt;使用しているパッケージの依存パッケージのバージョンを指定するのに、&lt;code&gt;npm&lt;/code&gt;を使用している場合は &lt;code&gt;npm-force-resolutions&lt;/code&gt;を使うと固定できますが、 &lt;code&gt;yarn berry&lt;/code&gt; (yarn v2, v3) を使用する場合はyarn単体で指定することができます。&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.npmjs.com/package/npm-force-resolutions" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--r7XxGAJ5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://static.npmjs.com/338e4905a2684ca96e08c7780fc68412.png" height="462" class="m-0" width="880"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.npmjs.com/package/npm-force-resolutions" rel="noopener noreferrer" class="c-link"&gt;
          npm-force-resolutions - npm
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          This packages modifies package-lock.json to force the installation of specific version of a transitive dependency (dependency of dependency), similar to yarn's [selective dependency resolutions](https://yarnpkg.com/lang/en/docs/selective-version-resolutio. Latest version: 0.0.10, last published: a year ago. Start using npm-force-resolutions in your project by running `npm i npm-force-resolutions`. There are 28 other projects in the npm registry using npm-force-resolutions.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--h1do8fu7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://static.npmjs.com/b0f1a8318363185cc2ea6a40ac23eeb2.png" width="32" height="32"&gt;
        npmjs.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;ユースケースとしては、依存パッケージに脆弱性があったときに元のパッケージの対応を待たなくともひとまず依存パッケージのバージョンを上げる（下げる）ことができるといった具合です。（もちろん元のパッケージが即座に対応してくれればそれでよいですが。）&lt;/p&gt;

&lt;h2&gt;
  
  
  環境
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;npm: 8.1.2&lt;/li&gt;
&lt;li&gt;yarn: 3.2.0&lt;/li&gt;
&lt;li&gt;node: v16.13.2&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  指定方法
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;yarn &lt;span class="nb"&gt;set &lt;/span&gt;resolution &amp;lt;descriptor&amp;gt; &amp;lt;resolution&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;のコマンドを実行します。&lt;/p&gt;

&lt;p&gt;たとえば、 &lt;code&gt;minimist&lt;/code&gt; のバージョンを &lt;code&gt;^1.2.0&lt;/code&gt; から &lt;code&gt;^1.2.6&lt;/code&gt; に上げるときは以下のようになります。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;yarn &lt;span class="nb"&gt;set &lt;/span&gt;resolution minimist@npm:^1.2.0 ^1.2.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;実行すると &lt;code&gt;yarn.lock&lt;/code&gt; でそのパッケージのバージョンが更新されていたり、 &lt;code&gt;.yarn/cache&lt;/code&gt; のパッケージのZIPファイルが更新されてたりします。&lt;/p&gt;

&lt;h2&gt;
  
  
  注意
&lt;/h2&gt;

&lt;p&gt;強制的にバージョン指定したため元のパッケージが意図しない動作になることがあります。&lt;/p&gt;

&lt;h2&gt;
  
  
  参考
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;yarn set resolution&lt;/code&gt;: &lt;a href="https://yarnpkg.com/cli/set/resolution"&gt;https://yarnpkg.com/cli/set/resolution&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>yarn</category>
    </item>
    <item>
      <title>ArtifactsにアップしたファイルのURLをSlackに通知する</title>
      <dc:creator>Yuta Goto</dc:creator>
      <pubDate>Fri, 10 Dec 2021 11:19:45 +0000</pubDate>
      <link>https://dev.to/yutagoto/artifactsniatupusitahuairunourlwoslacknitong-zhi-suru-25c6</link>
      <guid>https://dev.to/yutagoto/artifactsniatupusitahuairunourlwoslacknitong-zhi-suru-25c6</guid>
      <description>&lt;p&gt;CircleCIのArtifactにアップロードしたファイルのURLをSlackに通知する仕組みを作ります。作業リポジトリは以下です。&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/YutaGoto" rel="noopener noreferrer"&gt;
        YutaGoto
      &lt;/a&gt; / &lt;a href="https://github.com/YutaGoto/artifacts-sample" rel="noopener noreferrer"&gt;
        artifacts-sample
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Artifacts Sample&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;artifacts-sample&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;created by &lt;a href="https://github.com/vivliostyle/create-book" rel="noopener noreferrer"&gt;create-book&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;References&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;VFM &lt;a href="https://vivliostyle.github.io/vfm/#/vfm" rel="nofollow noopener noreferrer"&gt;https://vivliostyle.github.io/vfm/#/vfm&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Vivliostyle CLI &lt;a href="https://github.com/vivliostyle/vivliostyle-cli#readme" rel="noopener noreferrer"&gt;https://github.com/vivliostyle/vivliostyle-cli#readme&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Vivliostyle Themes &lt;a href="https://github.com/vivliostyle/themes#readme" rel="noopener noreferrer"&gt;https://github.com/vivliostyle/themes#readme&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Awesome Vivliostyle &lt;a href="https://github.com/vivliostyle/awesome-vivliostyle#readme" rel="noopener noreferrer"&gt;https://github.com/vivliostyle/awesome-vivliostyle#readme&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Vivliostyle (GitHub) &lt;a href="https://github.com/vivliostyle" rel="noopener noreferrer"&gt;https://github.com/vivliostyle&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Vivliostyle &lt;a href="https://vivliostyle.org" rel="nofollow noopener noreferrer"&gt;https://vivliostyle.org&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/YutaGoto/artifacts-sample" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;
 

&lt;p&gt;サンプルとしてvivriostyleでビルドして出来上がったpdfファイルをArtifactとしてアップロードしています。&lt;/p&gt;

&lt;h2&gt;
  
  
  アーティファクトのアップロード
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://circleci.com/docs/ja/2.0/artifacts/" rel="noopener noreferrer"&gt;https://circleci.com/docs/ja/2.0/artifacts/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;公式にある通り、 &lt;code&gt;store_artifacts&lt;/code&gt;にパスを指定します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;executor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;node/default&lt;/span&gt;
      &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;lts-browsers'&lt;/span&gt;
    &lt;span class="na"&gt;working_directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;~/project&lt;/span&gt; &lt;span class="c1"&gt;# 作業用ディレクトリ指定&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;checkout&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;node/install-packages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;cache-path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;~/project/node_modules&lt;/span&gt;
          &lt;span class="na"&gt;override-ci-command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn install&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn build&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mkdir ~/project/artifacts&lt;/span&gt; &lt;span class="c1"&gt;# アップロード用ディレクトリ生成&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mv output.pdf ~/project/artifacts/output.pdf&lt;/span&gt; &lt;span class="c1"&gt;# pdfファイルの移動&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;store_artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;~/project/artifacts&lt;/span&gt; &lt;span class="c1"&gt;# アップロード&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  URLの取得
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://circleci.com/docs/api/v1/#download-an-artifact-file" rel="noopener noreferrer"&gt;https://circleci.com/docs/api/v1/#download-an-artifact-file&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CircleCIのAPIにリクエストして環境変数に保存します。&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;artifacts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET &lt;span class="s2"&gt;"https://circleci.com/api/v2/project/github/&lt;/span&gt;&lt;span class="nv"&gt;$CIRCLE_PROJECT_USERNAME&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$CIRCLE_PROJECT_REPONAME&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$CIRCLE_BUILD_NUM&lt;/span&gt;&lt;span class="s2"&gt;/artifacts"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Accept: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Circle-Token: &lt;/span&gt;&lt;span class="nv"&gt;$CIRCLE_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="c"&gt;# APIをたたいてレスポンス値を代入する&lt;/span&gt;
&lt;span class="nv"&gt;artifact0&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$artifacts&lt;/span&gt; | jq &lt;span class="s1"&gt;'.items[0].url'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="c"&gt;# jqコマンドでurlの文字列を取得する&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"export ARTIFACT0=&lt;/span&gt;&lt;span class="nv"&gt;$artifact0&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$BASH_ENV&lt;/span&gt; &lt;span class="c"&gt;# 環境変数に登録する&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;変数に関しては過去記事もありますので合わせてみてください。&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/yutagoto" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F43436%2Ff3e254d5-74cf-4d61-a093-3d121f9e9b38.png" alt="yutagoto"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/yutagoto/circleci-1d5c" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;CircleCIで変数を扱う&lt;/h2&gt;
      &lt;h3&gt;Yuta Goto ・ Aug 11 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#circleci&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Slackに通知
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://circleci.com/developer/ja/orbs/orb/circleci/slack" rel="noopener noreferrer"&gt;https://circleci.com/developer/ja/orbs/orb/circleci/slack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CircleCIのSlackOrbを使うと簡単に通知させることができます。メッセージの組み立てはSlackのBlock Kit Builderを使っています。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://app.slack.com/block-kit-builder/" rel="noopener noreferrer"&gt;https://app.slack.com/block-kit-builder/&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;slack/notify&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt; &lt;span class="c1"&gt;# 常に通知させる&lt;/span&gt;
          &lt;span class="na"&gt;custom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;{&lt;/span&gt;
              &lt;span class="s"&gt;"blocks": [&lt;/span&gt;
                &lt;span class="s"&gt;{&lt;/span&gt;
                  &lt;span class="s"&gt;"type": "section",&lt;/span&gt;
                  &lt;span class="s"&gt;"text": {&lt;/span&gt;
                    &lt;span class="s"&gt;"type": "mrkdwn",&lt;/span&gt;
                    &lt;span class="s"&gt;"text": "Book Artifacts &amp;lt;${ARTIFACT0}&amp;gt;"&lt;/span&gt;
                  &lt;span class="s"&gt;}&lt;/span&gt;
                &lt;span class="s"&gt;}&lt;/span&gt;
              &lt;span class="s"&gt;]&lt;/span&gt;
            &lt;span class="s"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  結果
&lt;/h2&gt;

&lt;p&gt;正しく登録できると以下の画像のようなSlack通知が来ると思います。リンククリックしたら実際にPDFファイルがブラウザで確認ができます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqj8j7kzze09sheydz4zl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqj8j7kzze09sheydz4zl.png" alt="slack"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>circleci</category>
      <category>slack</category>
    </item>
    <item>
      <title>CircleCIを使用してVercelにデプロイする</title>
      <dc:creator>Yuta Goto</dc:creator>
      <pubDate>Sat, 02 Oct 2021 15:33:03 +0000</pubDate>
      <link>https://dev.to/yutagoto/circleci-vercel-208g</link>
      <guid>https://dev.to/yutagoto/circleci-vercel-208g</guid>
      <description>&lt;p&gt;Vercelにはgit pushを検知してDeployする仕組みがあるが、lintやtestしてからのデプロイはgit push検知の状態ではできないのでvercelのコマンドを使用してCDツールに組み込む。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vercel.com/cli"&gt;https://vercel.com/cli&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  準備
&lt;/h2&gt;

&lt;p&gt;vercelのgit integrationを切っておく。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EALhUJzF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u5dnkpze0f497e0qui3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EALhUJzF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u5dnkpze0f497e0qui3e.png" alt="vercel git repository setting"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vercelの個人設定からCircleCIで使用するTokenを生成する。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HF56iCRO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eupqjf4y3dgbsy167kuo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HF56iCRO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eupqjf4y3dgbsy167kuo.png" alt="Vercel Token"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Vercelで生成したTokenをCircleCIの環境変数にセットする。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0hSz1m9o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cy2azdjbvfxh78xbfajz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0hSz1m9o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cy2azdjbvfxh78xbfajz.jpg" alt="CircleCI Env"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  実装
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;yarn add&lt;/code&gt; でvercelコマンドを準備し、Scriptを組んでおくと楽に設定できる。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add &lt;span class="nt"&gt;-D&lt;/span&gt; vercel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vercel --token $VERCEL_TOKEN --prod --confirm"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;--confirm&lt;/code&gt; はデプロイするための質問をスキップさせることができる。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vercel.com/docs/cli#commands/overview/unique-options/confirm"&gt;https://vercel.com/docs/cli#commands/overview/unique-options/confirm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.circleci/config.yml&lt;/code&gt; に設定を書く。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .circleci/config.yml&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.1&lt;/span&gt;

&lt;span class="na"&gt;orbs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;circleci/node@4.7&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;working_directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;~/[ProjectName]&lt;/span&gt;
    &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;circleci/node:latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;checkout&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;install&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn install&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn deploy&lt;/span&gt;

&lt;span class="na"&gt;workflows&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;filters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;vercel --token $VERCEL_TOKEN --prod --confirm&lt;/code&gt; を実行すると現在のディレクトリがプロジェクト名として認識されデプロイされるので、 ymlファイルの &lt;code&gt;working_directory:&lt;/code&gt; の &lt;code&gt;[ProjectName]&lt;/code&gt; の部分をきちんと設定すれば意図したプロジェクト名でデプロイすることができる。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rkOBUGik--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mjja3zitw5agdyt55ttd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rkOBUGik--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mjja3zitw5agdyt55ttd.jpg" alt="CICD"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CIの実行結果に本番用のURLが出力されるので、そこからアクセスすることも可能になっている。&lt;/p&gt;

</description>
      <category>circleci</category>
      <category>vercel</category>
    </item>
    <item>
      <title>CircleCIのRust OrbでNightly版を使う</title>
      <dc:creator>Yuta Goto</dc:creator>
      <pubDate>Thu, 19 Aug 2021 17:07:19 +0000</pubDate>
      <link>https://dev.to/yutagoto/circleci-rust-orb-nightly-2hm8</link>
      <guid>https://dev.to/yutagoto/circleci-rust-orb-nightly-2hm8</guid>
      <description>&lt;p&gt;CircleCIのRustOrbsを使うときデフォルトではStable版になっています。最近のRustのバージョンで&lt;a href="https://github.com/rust-lang/rust-clippy"&gt;Clippy&lt;/a&gt;を使うときはNightlyに切り替える必要があります。&lt;/p&gt;

&lt;p&gt;特別な用意されたコマンドは実装されていないので普通に書きます。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .ciecleci/config.yml&lt;/span&gt;

&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.1&lt;/span&gt;

&lt;span class="na"&gt;orbs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;rust&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;circleci/rust@1.5.0&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;circleci/rust:latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;checkout&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rustup default nightly&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rust/clippy&lt;/span&gt;

&lt;span class="na"&gt;workflows&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;lint&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---jTXuXxB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5evjvmwaaba4oedlgvna.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---jTXuXxB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5evjvmwaaba4oedlgvna.png" alt="CircleCI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://circleci.com/developer/orbs/orb/circleci/rust"&gt;https://circleci.com/developer/orbs/orb/circleci/rust&lt;/a&gt;&lt;/p&gt;

</description>
      <category>circleci</category>
      <category>rust</category>
    </item>
    <item>
      <title>Discord Slash Commandをつくる</title>
      <dc:creator>Yuta Goto</dc:creator>
      <pubDate>Wed, 21 Jul 2021 14:32:34 +0000</pubDate>
      <link>https://dev.to/yutagoto/discord-slash-command-3h37</link>
      <guid>https://dev.to/yutagoto/discord-slash-command-3h37</guid>
      <description>&lt;p&gt;DiscordのSlashコマンドを使ってみます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://discord.com/developers/docs/interactions/slash-commands" rel="noopener noreferrer"&gt;https://discord.com/developers/docs/interactions/slash-commands&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  アプリの作成
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://discord.com/developers/applications" rel="noopener noreferrer"&gt;https://discord.com/developers/applications&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Developer PortalのApplicationsから新規作成します。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F72pg79nxx91rj0jbdreo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F72pg79nxx91rj0jbdreo.png" alt="6cdf0c93-e499-491a-a1aa-b897f9dde692"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;作成したら、OAuth2の設定ページに遷移して、OAuth2 URL Generatorの下にあるSCOPESから &lt;code&gt;Bot&lt;/code&gt;, &lt;code&gt;applications.commands&lt;/code&gt; を選択して、さらに &lt;code&gt;Bot Permissions&lt;/code&gt; の &lt;code&gt;Send Meesages&lt;/code&gt; にチェックを入れます。（必要に応じて追加でチェックを入れてください）&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8bbvazx1jwgyq5vaoya3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8bbvazx1jwgyq5vaoya3.png" alt="336c21e0-e3b4-48b5-9080-7803bafa178a"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SCOPESにあるURLにアクセスしてBOTユーザをサーバーに招待します。&lt;/p&gt;

&lt;p&gt;ここでBOTの下準備は完了です。&lt;/p&gt;

&lt;h2&gt;
  
  
  スラッシュコマンドの登録
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://discord.com/developers/docs/interactions/slash-commands#registering-a-command" rel="noopener noreferrer"&gt;https://discord.com/developers/docs/interactions/slash-commands#registering-a-command&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;公式のドキュメントにある通りスクリプトを組んで実行します。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://discord.com/api/v8/applications/&amp;lt;APPLICATION ID&amp;gt;/guilds/&amp;lt;GUILD ID&amp;gt;/commands&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;blep&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Send a random adorable animal photo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;options&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;animal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The type of animal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;required&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;choices&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dog&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;animal_dog&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;animal_cat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Penguin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;animal_penguin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;only_smol&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Whether to show only baby animals&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;required&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bot &amp;lt;BOT TOKEN&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;特定のサーバーでのみ使用するのであれば &lt;code&gt;&amp;lt;GUILD ID&amp;gt;&lt;/code&gt; を指定します。&lt;br&gt;
このスクリプトを実行して成功すれば201が表示されて終了します。&lt;br&gt;
特定のサーバーでのみのコマンドであれば即時反映されるので、実際にDiscord上でも確認ができます。&lt;code&gt;/&lt;/code&gt; を入力すると候補に &lt;code&gt;/blep&lt;/code&gt; が表示されるはずです。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9bh6di572z4esjsgj8gu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9bh6di572z4esjsgj8gu.png" alt="1cb19898-9309-4d47-97bd-790333eed9fe"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ただこのままコマンドを送信してもエラーとなり何も発生しないので、ひとまずコマンドを送信したらBOTがメッセージを送信する処理を実装します。&lt;/p&gt;
&lt;h2&gt;
  
  
  コマンド送信後の実装
&lt;/h2&gt;

&lt;p&gt;今回、本番環境では Cloudflare Workers KV を使用します。GoogleCloudRunなどのサーバレスのものを利用しても問題ないですが、CloudRunはアクセスがあってから起動するまでに時間がかかってしまい、Discord側でタイムアウト判定になってしまう可能性があります。Cloudflare Workers KVは起動がCloudRunよりもかなり早いので正常にレスポンスできるはずです。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.cloudflare.com/ja-jp/products/workers-kv/" rel="noopener noreferrer"&gt;https://www.cloudflare.com/ja-jp/products/workers-kv/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cloudflare Workers KVのセットアップは割愛します。&lt;a href="https://developers.cloudflare.com/workers/" rel="noopener noreferrer"&gt;https://developers.cloudflare.com/workers/&lt;/a&gt; に環境構築からデプロイまでかかれています。&lt;br&gt;
外部ライブラリを利用するのでWebpackも利用します。&lt;/p&gt;
&lt;h3&gt;
  
  
  Discordのリクエストを受け付ける
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;discord-interactions&lt;/code&gt; を使って実装します。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/discord-interactions" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/discord-interactions&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;このコードは何かしらコマンドのリクエストがあれば &lt;code&gt;pong&lt;/code&gt; を返却するだけのものになっています。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff8hu9lwzsoswoendbe6s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff8hu9lwzsoswoendbe6s.png" alt="スクリーンショット 2021-07-21 AM1.09.05"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;以下のコードでヘッダーがちゃんとDiscordから来たものかを判定します。Discordで &lt;code&gt;Interactions Endpoint URL&lt;/code&gt; を登録する際にあえて誤ったリクエストヘッダーがついたリクエストがくるので、それの判定を行います。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;verifyKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;arrayBuffer&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;X-Signature-Ed25519&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;X-Signature-Timestamp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;discord_public_key&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;以降の処理は正しい形式でJSONを返却します。 &lt;a href="https://discord.com/developers/docs/interactions/slash-commands#responding-to-an-interaction" rel="noopener noreferrer"&gt;https://discord.com/developers/docs/interactions/slash-commands#responding-to-an-interaction&lt;/a&gt; にもサンプルが書いています。&lt;/p&gt;

&lt;h3&gt;
  
  
  デプロイ
&lt;/h3&gt;

&lt;p&gt;外部パッケージを使用しているのでwebpackした後のコードをデプロイします。webpackやその設定の説明は端折ります。&lt;/p&gt;

&lt;p&gt;デプロイもcloudflareのチュートリアルにある通りにコマンド一発で完了します。 &lt;a href="https://developers.cloudflare.com/workers/get-started/guide#8-publish-your-project" rel="noopener noreferrer"&gt;https://developers.cloudflare.com/workers/get-started/guide#8-publish-your-project&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;デプロイが完了したらCloudflareのWorkers一覧ページにアクセスして、そこに表示されているURLを確認します。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7zw641l7icpolkw110j7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7zw641l7icpolkw110j7.png" alt="Screenshot 2021-07-21 at 01-21-22 Workers Account Cloudflare - Web Performance Security"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;そこに表示されているURLを Discordのアプリケーション設定ページの &lt;code&gt;discord-interactions&lt;/code&gt; にペーストしてセーブしてチェックがパスしたら完了です。&lt;/p&gt;

</description>
      <category>discord</category>
      <category>discordslashcommand</category>
    </item>
  </channel>
</rss>
