メインコンテンツまでスキップ

リソース

クックブック

確認済みの機能の上に構築された実践的なレシピです。公開する前に、それぞれを自分のインスタンスで検証・ドライランしてください。

別のフィールドに基づいてフィールドを設定する (taskActionDone)

if (issue.field("Requirement Type").is("Roadmap Requirement")) {
issue.update({ Priority: "Medium" })
api.log("Priority set to Medium")
}

要件がレビュー中の間、更新をブロックする (taskPreAction)

if (
issue.issueType.is("Requirement") &&
issue.status.is("In Review") &&
issue.anyFieldChanged()
) {
api.reject("Requirements cannot be updated while In Review")
}

フィールドが特定の値に変わったときだけ動作する (event / taskActionDone)

if (issue.status.changedTo("Blocked")) {
issue.update({ Priority: "Highest" })
api.log("Escalated blocked issue")
}

ステータスカテゴリの変更時に担当者をコメントでメンションする (event)

if (
issue.anyStatusChanged() &&
issue.statusCategory.changedTo("in_progress") &&
issue.issueType.is("User Story")
) {
issue.addComment({
text: "Status moved into progress.",
mentions: [issue.assignee.mention()]
})
}

.mention() は 1.1 では再検証待ちです。依拠する前にドライランで確認してください。

アクション後の外部 Webhook (taskActionDone / event)

if (issue.status.changedTo("Done")) {
const response = await api.fetchExternal({
url: "https://example.com/hooks/ones-status",
method: "POST",
headers: { Authorization: "Bearer " + vars.get("WEBHOOK_TOKEN") },
body: { issueUUID: context.taskUUID, status: "Done" },
timeoutMs: 5000
})
api.log("Webhook status: " + response.statusCode)
}

冪等なイベントリスナー (event)

const eventID = String(event.eventID || context.eventID || "")
const key = "event:" + eventID
if (eventID && (await api.storage.get(key))) {
return // already processed
}
if (issue.field("Found in Production").changedTo("Yes")) {
issue.update({ Priority: "Highest" })
}
if (eventID) {
await api.storage.set(key, true)
}

issue.search によるスケジュールされたクエリ (timer)

const issues = await issue.search({
where: { issueType: "Requirement", status: "In Review" },
select: ["Priority"],
limit: 100
})
for (const item of issues) {
api.log("In review: " + item.field("Priority").value)
}

Cursor を使って複数ページの課題を連続処理する (timer または Run now)

let cursor = ""

do {
const issues = await issue.search({
where: { issueType: "Requirement", status: "In Review" },
limit: 100,
cursor
})

for (const item of issues) {
api.log("In review: " + item.key)
}

cursor = issues.pageInfo.hasNextPage
? issues.pageInfo.endCursor
: ""
} while (cursor)

limit は 1 回の呼び出しで返す課題数を指定します。連続してページングする場合は、現在のページの pageInfo.endCursor を次の呼び出しに渡します。

子の予定終了日を親(階層)の範囲内に保つ (taskPreAction)

if (context.action === "update" && issue.field("Planned end date").changed()) {
const next = issue.field("Planned end date").newValue
if (issue.hierarchy("Upstream").any.field("Planned end date").isBefore(next)) {
api.reject("The planned end date must not be later than the upstream (parent) issue.")
}
}

関連付けられた前提課題が完了するまで遷移をブロックする (taskPreAction)

if (issue.status.changedTo("In Progress")) {
try {
if (!issue.linkedIssues("Prerequisites").all.statusCategory.is("done")) {
api.reject("Finish the prerequisite issues before starting this issue.")
}
} catch (e) {
api.reject("Cannot verify prerequisites — try again.")
}
}

期限切れの課題について担当者にスケジュールでメール送信する (timer; オンプレミスのみ)

const overdue = await issue.search({
where: { status: "In Progress" },
select: ["Assignee"],
limit: 100
})
for (const item of overdue) {
api.notify({
channel: "email",
recipients: [item.assignee.value], // ONES user UUID
title: "An issue needs your attention",
message: "This issue has stayed in progress and may be overdue.",
issue: item.uuid
})
}

配信は自動的に再試行されません — 通知ごとの結果は 実行ログ で確認してください。api.notify を参照してください。


制限事項とロードマップ

ONES ですでにネイティブ(スクリプト不要) — Jira では ScriptRunner のアドオンを必要とするいくつかのものが、ONES には組み込まれています(条件付きフィールド表示、依存選択肢のフィルタリング、親子のロールアップと計算フィールド)。そのため、スクリプトをまったく必要としません。ネイティブ設定になるものを参照してください。

まだ利用できないもの

  • 条件付きの必須/非空検証 — 例:「フィールド A = X なら、フィールド B は空にできない」、およびフォーム入力中のポップアッププロンプト。(値ベースの条件付き検証 — 「A = a なら B は 1 にできない」 — は taskPreAction バリデーター経由でサポートされています。)

ロードマップ上 🔜

  • SaaS デプロイ(オンプレミスは現在利用可能)
  • 条件付きの必須/非空検証 / インタラクティブなフォーム内プロンプト
  • 専用のクエリ UI(api.queryIssues(...) 経由のスクリプト内クエリは現在利用可能)
  • 権限 / ロール(作成者 vs. 実行、スコープ設定)

未定義 ❓

  • バージョン履歴、実行ログ、イベントログ、システム監査ログの保持/エクスポート

FAQ、用語集とフィードバック

FAQ (初期セット — 質問が来るたびに拡充)

  • どの言語を使えますか? JavaScript、TypeScript、Groovy(Groovy はオンプレミスのみ、外部ランナー経由)。
  • オンプレミスで動作しますか? はい — オンプレミスは現在利用可能で、SaaS は近日提供予定です。
  • 自動化と同じですか? いいえ — 自動化はノーコードルールで日常的な処理を担い、ONEScript はその下にあって、ノーコードが終わるところから引き継ぐコードレイヤーです。
  • データを変更せずにテストできますか? はい — ドライランを使ってください。ドライランはデータを変更しません。Run now は本番実行であり、条件を満たす最新の公開済みスクリプトにだけ表示され、確認操作が必要です。
  • スクリプトを自動実行させるには? 公開してから、自動化 → トリガーバインディング(スケジュールの場合はタイマールール)でバインドします。
  • 1 つのスクリプトまたはタイマールールの実行を確認するには? スクリプトの More またはタイマールールカードから Execute history を開きます。対象で絞り込まれた実行ログが表示されます。
  • スクリプトが何を変更したかは誰が見られますか? 課題の履歴(*「ONEScript が……を更新しました」*として表示)、実行ログ、システム監査ログです。
  • AI アシスタントを使ってスクリプトを書けますか? はい — AI スキルSkill.md)をダウンロードしてアシスタントに読み込ませてください。AI アシスタントで作成するを参照してください。

用語集

  • トリガーバインディング — 公開済みスクリプトをプロジェクト/課題タイプ/アクションに接続し、イベントやワークフローアクションで実行されるようにする(自動化の配下)。
  • タイマールール — スクリプトをスケジュールで実行する(自動化の配下)。
  • ドライラン — 変更を書き込まずに、スクリプトが何をするかを確認するために実行する。
  • Run now — 条件を満たす最新の公開済みバージョンを本番データに対して 1 回実行する。ドライランでもトリガーでもない。
  • Execute history — スクリプトまたはタイマールールで絞り込んだ実行ログを開く。
  • Cursorissue.search(...) が返すページング継続位置。次のページを読み取るために使用する。
  • セマンティック構文 — フィールド/ステータス/選択肢を表示名で解決する、読みやすい作成スタイル。
  • 実行ログ / イベントログ — それぞれ実行結果と、イベント配信/ルールマッチング。
  • issue.search(...) — 標準のセマンティッククエリヘルパー。条件で課題を検索し、選択したフィールドを読み取る。リファレンス → データのクエリを参照してください。
  • ONESQL — ONES のクエリ言語。高度なエスケープハッチとして api.queryIssues(...) 経由でスクリプト内で使用する。

変更履歴

  • 1.1.3 — ネイティブの浮動小数点数および Selection スクリプトフィールド、Run now、秒 / 分 / 時間 / 日単位のタイマールール、正確な実行履歴への入口、issue.search(...) の Cursor ページング、現在のリクエスト元の権限で実行する呼び出し元モードの課題検索、更新、コメント、ステータス遷移を追加しました。
  • 1.1.1issue.worklog ワークフローガード、表示されている課題キーを使う Raw JSON ドライラン、信頼できるプロジェクト / 課題タイプのスコープ解決とルールの即時反映を追加し、REST エンドポイント、安全なログ、実行容量の契約を明確化しました。
  • 1.1.0 — セマンティックフィールド構文、issue.search(...)api.notify(...)、関連 / 階層ヘルパー、変更前フィールド読み取りを拡張しました。

フィードバック(早期プレビュー)。 ONEScript は早期プレビューであり、それを使うチームによって形作られています。あなたのスクリプトに何が必要かをお知らせください——フィードバックを送る →