やりたいこと・現状と前提
やりたいこと
- GitHubワークフローでNext.jsのビルドとFTPサーバーへのアップロードをしたい
main
ブランチへのプルリクがクローズするとワークフローが動くように組む
現状
- プルリクのトリガーとFTPアップは検証済みで
.github/workflows/main.yml
の記述に問題はない - Next.jsのビルドはローカル上では成功している
前提
前提としてコンテンツ管理をヘッドレスCMSのNewtでしていて、Next.jsで下記のように展開できるように組んでいます。
NewtのAPIにリクエストする関数
import { createClient } from 'newt-client-js'
const client = createClient({
spaceUid: process.env.NEWT_SPACE_UID + '',
token: process.env.NEWT_CDN_API_TOKEN + '',
apiType: 'cdn',
})
export const getArticles = async () => {
const { items } = await client.getContents<NewtArticle>({
appUid: process.env.NEWT_APP_UID_TECH_BLOG + '',
modelUid: process.env.NEWT_APP_UID_TECH_BLOG_ARTICLE + '',
query: {
select: ['_id', '_sys', 'slug', 'title', 'pickup', 'issue', 'body', 'thumbnail', 'categorys'],
},
})
return items
}
ブログ詳細を展開するpage.tsx
export async function generateStaticParams() {
const articles = await getArticles()
return articles.map( article => (
{
slug: article.slug
}
))
}
export default async function BlogDetail({
params
}: Props) {
const { slug } = params
const article = await getArticleBySlug(slug)
if (!article) return
return <>
{/* ブログ一覧を展開するJSX */}
</>
}
.github/workflows/main.yml
の記述
name: Next.js Build & FTP Upload
on:
pull_request:
branches:
- main
types: [closed]
repository_dispatch:
types: [Newt_Manual_Deploy]
jobs:
ftp-deploy:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- name: Install Dependencies
run: yarn install
- name: Build
run: yarn build
- name: Sync files
uses: SamKirkland/FTP-Deploy-Action@4.3.0
with:
server: ${{ secrets.FTP_SERVER }}
username: ${{ secrets.FTP_USERNAME }}
password: ${{ secrets.FTP_PASSWORD }}
server-dir: ${{ secrets.FTP_SERVER_DIR }}
local-dir: ./out/
GitHubワークフローでの401エラーの詳細と原因
上記のmain.yaml
のステップInstall dependenciesまでは成功していて、buildのフェーズにて下記の401エラーが返ってきました。
Collecting page data ...
401 Unauthorized: {
"status": 401,
"code": "Unauthorized",
"message": "The authorization token was invalid.",
"request": {
"method": "get",
"headers": {
"Accept": "application/json, text/plain, */*",
"Authorization": "***",
"User-Agent": "axios/1.7.4",
"Accept-Encoding": "gzip, compress, deflate, br"
},
"url": "https://undefined.cdn.newt.so/v1/undefined/undefined?select=_id%2C_sys%2Cslug%2Ctitle%2Cpickup%2Cbody%2Cthumbnail%2Ccategorys"
}
}
401は認証エラーなので、Newt側で設定したアクセストークンを正しく指定できていない可能性が高いです。
というかそもそも、request
のurl
プロパティの値がどう見ても正しくなく、undefined
だらけになっています。
エラーの原因は.env.local
ファイルを参照できていないから
原因は超シンプルで、Newtとの通信に関わる認証情報はすべて.env.local
ファイルで管理していて、当然そのファイルは.gitignore
でリモートには上げていないので、GitHubのワークフロー上で参照できないからでした。
.env.local
はGitHubの管理下にはおかず、別の方法で参照できるようにすれば解決できます。
【解決策】GitHub Secretsで設定した値を参照してワークフロー中に.env.local
を出力する
上記の記事を参照させていただいて、やり方の候補は3つ。
echo
コマンドを使う方法Environment Variables
を使う方法secrets
を使う方法
色々確認して、GitHub Secretsで環境変数を設定してその値を参照して.env.local
ファイルを出力するのが、管理のしやすさと実装しやすさ的に楽でした。
実装方法
.github/workflows/main.yml
の記述
... [省略] ...
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- name: Install Dependencies
run: yarn install
- name: Create .env File
run: |
echo "${{ secrets.ENV_LOCAL }}" > $GITHUB_WORKSPACE/.env.local
- name: Build
run: yarn build
- name: Sync files
... [省略] ...
新たにCreate .env File
という記述を追加しています。secrets
にGitHub Secretsで設定した変数が格納されており、$GITHUB_WORKSPACE
はワークフロー中のプロジェクトルートを指しています。
これでワークフロー上でも、.env.local
ファイルを参照できるようになります。
GitHub Secretsの設定
GitHubの変数は下記の手順で設定できます。
GitHubのリポジトリ画面 > Settings > Secrets and variables
New repository secret
でプロパティ名と値を設定
これでmain.yaml
にて${{ secrets.__[設定したプロパティ]__ }}
と書けば参照できるようになります!