atlassian-cli はコミュニティによる独立したオープンソースプロジェクトです。Atlassian と提携・関連しておらず、Atlassian による承認、推奨、後援のいずれも受けておらず、Atlassian が提供する公式 CLI(acli)でもありません。製品名は互換性を示す目的でのみ使用しています。
手っ取り早い答え
atlassian-cli で CSV から Jira の課題を作成するには、ファイルの各行をループし、1 行につき 1 回 jira issue create を呼び出します。CSV をアップロードする専用のサブコマンドはありません。これは意図的な設計です。短いシェルのループなら、列とフィールドの対応付けが明示的になり、チームがすでに書き出しているどんな CSV でも扱え、ほかの自動化と並べてバージョン管理に置けます。
動作する最小の例は次のとおりです。ヘッダー行と summary、issue_type の 2 列を持つファイルから、DEV プロジェクトに 1 行につき 1 件の課題を作成します。
# Skip the header, create one issue per row
tail -n +2 issues.csv | while IFS=, read -r summary issue_type; do
atlassian-cli jira issue create \
--project DEV \
--issue-type "$issue_type" \
--summary "$summary"
done
このガイドの残りでは、この 1 行を実データに任せられるものへ育てます。フィールドの対応表、課題が作られる前にすべてを確認できるドライラン、カスタムフィールドの扱い、そして誤ったインポートを簡単に戻せるよう作成した課題キーをすべて記録する仕組みです。以下のコマンドはいずれもコマンドリファレンスで確認できます。
acli との違い。atlassian-cli はコミュニティによる独立したオープンソースプロジェクトです。Atlassian と提携・関連しておらず、Atlassian による承認、推奨、後援、保守のいずれも受けておらず、Atlassian が提供する公式 CLI(acli)でもありません。ベンダーによる一次サポートが必要な場合は acli を使ってください。Jira、Confluence、Bitbucket、JSM を横断し、ここで示すようなスクリプト化しやすくパイプに流しやすい出力を備えた無料の単一 Rust バイナリが欲しい場合は atlassian-cli を使ってください。
CSV ファイルを準備する
CSV には、設定したい Jira のフィールドごとに 1 列と、その列名を記したヘッダー行が必要です。構造は平たく、予測しやすく保ってください。バックログ向けの典型的なインポートファイルは次のようになります。
# issues.csv
summary,issue_type,assignee,sprint_id
"Fix login timeout on SSO redirect",Bug,alice@example.com,25446
"Add rate-limit headers to public API",Story,bob@example.com,25446
"Write onboarding runbook",Task,,
"Upgrade Postgres to 16",Task,carol@example.com,
あとで困らないための習慣をいくつか挙げます。
- カンマを含む値は引用符で囲む。行ごとの列数が安定します。
- 該当しないフィールドは空欄にする。プレースホルダーを作らないでください。空欄はループの中で判定しやすくなります。
- 課題タイプ、スプリント ID、アカウントのメールアドレスは Jira の値をそのまま使う。
issue_typeの打ち間違いは API に拒否されます。黙って修正されることはありません。
自分のインスタンスに合った列を持つテンプレートが欲しい場合は、まず既存の課題をいくつか CSV に書き出し、そこから編集してください。
# Export a few issues as a starting template
atlassian-cli jira issue search \
--jql "project = DEV order by created desc" \
--limit 5 \
--format csv --output template.csv
CSV の列を Jira のフィールドに対応付ける
フィールドの対応付けは間違えやすい部分なので、明示的にしておきます。各列は jira issue create のフラグになるか、作成後の課題に対する追加コマンドになります。以下の表はよくあるケースをまとめたものです。
| CSV の列 | 対応先 | 備考 |
|---|---|---|
summary |
jira issue create の --summary |
必須。すべての課題が必ず持つフィールドです。 |
issue_type |
--issue-type |
プロジェクトに存在するタイプと一致させます(Task、Bug、Story など)。 |
project |
--project |
プロジェクトキー。ファイル全体で固定のことが多いため、直接書いても構いません。 |
sprint_id |
--sprint |
数値のスプリント ID。カスタムフィールドの ID は不要です。 |
| カスタムフィールド | --field 'customfield_10010={...}' |
ID は jira fields list で調べます。値は JSON です。 |
assignee |
jira issue assign <key> (after create) |
新しい課題キーが分かってから実行します。 |
status |
jira issue transition <key> (after create) |
課題を既定のワークフローの状態から移します。 |
この分割には意味があります。jira issue create は作成時点で存在するフィールドを設定し、担当者とステータスは課題キーを受け取ってから別のステップで設定するのが最もすっきりします。こうすると各コマンドが小さく保たれ、失敗の原因を特定の行に結び付けやすくなります。
インポートのループ
ここまでをまとめて、繰り返し実行できるスクリプトにします。先ほどの 4 列の CSV を読み、各課題を作成し、該当する列があれば担当者を割り当ててスプリントに入れます。
#!/bin/bash
# import-issues.sh - create Jira issues from a CSV file
set -euo pipefail
CSV="issues.csv"
PROJECT="DEV"
PROFILE="prod"
DRY_RUN="${DRY_RUN:-1}" # 1 = preview only, 0 = create for real
# Skip the header row, then read each column
tail -n +2 "$CSV" | while IFS=, read -r summary issue_type assignee sprint_id; do
if [ "$DRY_RUN" = "1" ]; then
echo "[DRY-RUN] would create [$issue_type] $summary"
echo " assignee=${assignee:-none} sprint=${sprint_id:-none}"
continue
fi
# Build optional flags only when the column has a value
extra=()
[ -n "$sprint_id" ] && extra+=(--sprint "$sprint_id")
key=$(atlassian-cli jira issue create \
--profile "$PROFILE" \
--project "$PROJECT" \
--issue-type "$issue_type" \
--summary "$summary" \
"${extra[@]}" \
--format json | jq -r '.key')
echo "Created $key"
echo "$key" >> created-keys.txt
# Assign after creation when the column is filled
if [ -n "$assignee" ]; then
atlassian-cli jira issue assign "$key" \
--profile "$PROFILE" \
--assignee "$assignee"
fi
done
重要なのは 2 点です。extra=() の配列は、行にスプリント ID が実際にあるときだけ --sprint を追加するので、空欄が壊れたフラグになることはありません。そして --format json | jq -r '.key' がレスポンスから新しい課題キーを直接取り出します。これがあるから、担当者の割り当てと監査用のログが成り立ちます。
CSV の解析について。きれいなデータなら IFS=, で十分ですが、すべてのカンマで素朴に分割してしまいます。要約に引用符内のカンマが含まれる場合は、まずタブ区切りで書き出すか(IFS=$'\t')、Python の csv モジュールのような本物の CSV リーダーで解析し、その結果を同じ jira issue create の呼び出しに渡してください。
書き込む前にドライランする
課題の作成には取り消しボタンがないので、まずバッチ全体をプレビューしてください。jira issue create はすぐに書き込むため、ドライランはフラグではなくスクリプト側に置きます。先ほどのループの DRY_RUN 変数がまさにそのスイッチです。オンのときは、各行の課題タイプ、要約、解析したフィールドを出力し、実際の API 呼び出しは行いません。
# Preview every row without touching Jira
DRY_RUN=1 ./import-issues.sh
# Example output
# [DRY-RUN] would create [Bug] Fix login timeout on SSO redirect
# assignee=alice@example.com sprint=25446
# [DRY-RUN] would create [Story] Add rate-limit headers to public API
# assignee=bob@example.com sprint=25446
# Happy with the plan? Create them for real
DRY_RUN=0 ./import-issues.sh
これは、遷移や担当者の割り当てで --dry-run が標準のフラグとして用意されている一括操作と同じ、確認してから実行する習慣です。ここではその作法を作成にも当てはめています。ドライランの出力は差分のつもりで読んでください。行数を確認し、要約が空の行を探し、課題タイプの表記がプロジェクトの想定どおりかを確かめてから、DRY_RUN を 0 に切り替えます。
カスタムフィールド、担当者、ステータス
実際のバックログには要約以外の情報もあります。カスタムフィールドは --field フラグで指定し、その値は JSON です。カスタムフィールドは表示名ではなく ID で指定するので、まずフィールドの ID を調べます。
# List fields to find the customfield_ ID you need
atlassian-cli jira fields list --format json | jq -r '.[] | "\(.id)\t\(.name)"'
見つけたら作成のコマンドに追加します。選択リストのカスタムフィールドに対応する severity という CSV の列は、次のようになります。
atlassian-cli jira issue create \
--project DEV \
--issue-type Bug \
--summary "$summary" \
--field 'customfield_10010={"value":"Internal"}'
担当者とステータスは、課題キーが分かってからのほうが読みやすいので追加のコマンドにします。たとえば作成のコマンドが DEV-412 を返したあとなら、次のようになります。
# Set the assignee from the CSV's assignee column
atlassian-cli jira issue assign DEV-412 --assignee carol@example.com
# Move it out of the default state if the CSV has a status column
atlassian-cli jira issue transition DEV-412 --transition "In Progress"
ループと同じように、それぞれを if [ -n "$column" ] のガードで囲めば、該当する列が空の行はその手順を飛ばします。こうしておけば、1 つのスクリプトで要約だけの手早いインポートにも、項目を細かく指定したバックログにも対応できます。
課題キーの記録とロールバック
ループは新しい課題キーをすべて created-keys.txt に追記します。このファイルが安全網です。誤ったプロジェクトにインポートしてしまった場合や、列の対応付けを間違えた場合でも、作成時刻からの推測ではなく、取り消すべき対象の正確な一覧が手元にあります。
インポートを取り消すには、それらの課題キーを CLI に戻します。クローズ状態へ遷移させることも、そのまま削除することもできます。
# Move every imported issue to a terminal state
while read -r key; do
atlassian-cli jira issue transition "$key" --transition "Closed"
done < created-keys.txt
# Or delete them if they should never have existed
while read -r key; do
atlassian-cli jira issue delete "$key"
done < created-keys.txt
課題キーのログを残しておくと、インポートが成功したかどうかも確認できます。行数を数えて CSV の行数と比べたり、jira issue get で課題キーを再取得してフィールドが意図どおりに入ったかを確かめたりできます。残ってしまった課題や誤って作成した課題をより広く片づけるには、Jira プロジェクトクリーンアップランブックがこのログとよく合います。スケジュール実行のジョブや Webhook からインポートを起動したい場合は、Jira 自動化の実例のパターンが、同じコマンドをパイプラインに組み込む方法を示しています。
Jira の UI インポーターとの違い
Jira Cloud には、単発の対話的なインポート向けに、Web インターフェース内蔵の CSV インポーターがあります。ブラウザ上で対応付けのウィザードが案内してくれるので、一度スプレッドシートを渡されただけで繰り返す必要がない場合には良い選択肢です。
CLI のやり方が生きるのは、作業が繰り返されるときです。スクリプトは差分が取れ、レビューでき、CI や cron ジョブから実行できます。対応付けはコードであり、毎回クリックし直すドロップダウンではありません。まったく同じバッチをドライランでき、生成された課題キーを記録でき、同じツールでロールバックできます。インポートが定期的に発生する場合、別のシステムの出力に連動する場合、あるいは検索、遷移、担当者の割り当てを含むより大きなワークフローに組み込む必要がある場合、このループはウィザードにはできない形で規模を広げられます。
どちらも一括アップロード用のエンドポイントではありません。CLI も 1 行につき 1 回の作成呼び出しを行います。対話的な操作でも問題ない、非常に大きな一度きりの取り込みなら、UI のインポーターのほうが早く終わるかもしれません。2 回以上実行したいものは、すべてスクリプトに残してください。日々の作業もターミナルで管理しているなら、CLI での Jira タスク管理が同じコマンドを土台により広いワークフローを解説しています。
atlassian-cli を試す
Jira、Confluence、Bitbucket、JSM に対応する MIT ライセンスの無料バイナリがひとつ。CSV のインポートとその周辺をまとめてスクリプト化できます。
atlassian-cli をインストールよくある質問
atlassian-cli は課題の CSV を 1 つのコマンドで Jira にインポートできますか?
CSV をインポートする専用のサブコマンドはありません。CSV から Jira の課題を作成するには、短いシェルスクリプトで各行をループし、1 行につき 1 回 atlassian-cli jira issue create を呼び出します。対応付けが明示的になり、スクリプトをバージョン管理できますが、1 回のアップロードではなく課題 1 件ごとに API 呼び出しが 1 回発生します。
実際に課題を作成する前に CSV のインポートをドライランするには?
jira issue create はすぐに書き込むため、ドライランはフラグではなくスクリプト側に置きます。ループを DRY_RUN 変数で制御し、オンのときは各行について作成コマンドと解析したフィールドを出力して実際の呼び出しを飛ばします。まず DRY_RUN=1 で実行して出力を読み、それから DRY_RUN=0 にして実際に課題を作成します。
カスタムフィールドを含めて CSV の列を Jira のフィールドに対応付けるには?
標準のフィールドはフラグに対応します。要約は --summary、課題タイプは --issue-type、プロジェクトは --project、スプリントは --sprint です。カスタムフィールドは --field 'customfield_10010={"value":"Internal"}' で指定します。正確なカスタムフィールドの ID は atlassian-cli jira fields list で調べます。担当者とステータスは作成後に jira issue assign と jira issue transition で設定します。
CSV からのインポート後に新しい課題キーを記録するには?
jira issue create を --format json で実行し、jq -r '.key' で課題キーを取り出します。取り出した課題キーは created-keys.txt のようなログファイルに追記します。このログがあれば何が作成されたのかを正確に記録できるので、インポートを取り消す必要が出たときに、それらの課題を遷移させたり、担当者を変更したり、削除したりできます。