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

リファレンス

これは ONEScript スクリプトを書くための構文とヘルパーのリファレンスです。タスクベースのガイダンスについては、まずはじめにガイドをご覧ください。すぐに応用できるレシピについては、クックブックを参照してください。

ヘルパーは、データを読み書きするためにスクリプトオブジェクト(issueapieventselectionopenapi)に対して呼び出すメソッドです(例:issue.update(...)api.reject(...)issue.status.changedTo(...)selection.options.from(...))。一方、issue.field("Priority").valueselection.request.relations のようなアクセサーは、呼び出すメソッドではなく、読み取るプロパティです。


トリガー

スクリプトのトリガーは、いつ実行されるか、そして何が許可されるかを決めます。ONEScript は 8 種類のトリガータイプを提供します。

トリガーレベル実行されるタイミング設定場所
consoleL1(読み取り専用)スクリプトエディターからドライランを実行
taskPreActionL0変更がコミットされる。拒否できる自動化 → トリガーバインディング
taskActionDoneL1変更がコミットされた自動化 → トリガーバインディング
eventL1課題イベント(作成 / 更新)時自動化 → トリガーバインディング
timerL1スケジュール時自動化 → タイマールール
scriptedFieldL0浮動小数点数フィールドを算出するためリソース → スクリプトフィールド
scriptedFieldOptionsL1(読み取り専用)ネイティブのプルダウン / プルダウン(複数)Selection フィールドに選択肢を提供するためリソース → スクリプトフィールド
httpEndpointL1認証付きのインバウンド HTTP リクエスト時(POST /hooks/<slug>REST エンドポイント

トリガーポリシーマトリクス

L0 トリガーは同期的で高頻度のため、ネットワークもストレージも使えませんL1 トリガーは、読み取り/書き込みルールに従う範囲で、制御されたアダプターを使えます。

トリガーレベルネットワーク書き込みストレージ典型的な用途
consoleL1ありなしget のみ一回限りの読み取りチェック、メタデータ参照、安全なクエリ
taskPreActionL0なし課題フィールド / 拒否のみなし送信前のバリデーターとガード
taskActionDoneL1ありありget/set/deleteアクション後の更新、コメント、同期
eventL1ありありget/set/delete非同期リスナー、冪等な自動化
timerL1ありありget/set/deleteスケジュールされたクエリ/バッチ処理
scriptedFieldL0なしなしなし浮動小数点数フィールドの計算(オンプレミス)
scriptedFieldOptionsL1ありなしget のみネイティブ Selection の選択肢(オンプレミス)
httpEndpointL1ありありget/set/delete認証付きのインバウンド REST エンドポイント

現在のトリガーで許可されていないヘルパーは、公開前にエディターのインライン診断によってフラグが付けられます。

Run now は設定可能なトリガーではありません。条件を満たす最新の公開済みバージョンを 1 回だけ本番実行するエディター操作です。

skip(...)api.reject(...)、ランタイムタイムアウトは終端制御フローです。スクリプトコードでシグナルを捕捉しても、ホストヘルパー、ネットワーク、ストレージ、ログ、レスポンス、記録された効果は再度有効になりません。

taskPreAction のトリガーバインディングでは、プロジェクトと課題タイプでスコープを限定できます。ONEScript は現在の信頼できる課題から不足しているスコープを解決してから、バインディングを選択します。不一致が確定した場合は通常どおり続行します。適用される可能性のあるスコープ付きガードが未解決のまま残る場合にのみ、ONEScript は利用不可の理由でアクションをブロックし、スクリプトを実行しません。ガードの作成、有効化、無効化、編集、削除が成功すると、その結果は次のワークフローアクションから有効になり、キャッシュ期限を待つ必要はありません。

ワークベンチへのアクセス

ONEScript ワークベンチは onescript_workbench_access 権限ポイントで保護されています。明示的な拒否は HTTP 403 を返します。権限サービスが利用できない場合、ワークベンチ API リクエストは HTTP 503 を返します。


スクリプトコンテキストオブジェクト

スクリプト内では、次のオブジェクトを利用できます。

オブジェクト内容
issueコンテキストにある課題。フィールド、ステータス、担当者の読み取り・変更、コメントの追加ができる
eventトリガーとなったイベント(例:event.eventIDevent.changedField(...)
contextより低レベルのトリガーコンテキスト(context.taskUUIDcontext.action、変更フィールドの生スナップショット)
apiヘルパー:api.logapi.rejectapi.queryIssuesapi.storageapi.fetchExternal
varsリソース → 変数で定義した再利用可能な値とシークレット(vars.get("NAME")
selectionネイティブ Selection の選択肢ヘルパーと読み取り専用リクエストコンテキスト(selection.options.*selection.request.*
openapiカタログに基づく ONES OpenAPI ヘルパー(openapi.issue.*openapi.workflow.transit など)

Run now

Run now は、サーバーが再確認した最新の公開済みバージョンだけを実行します。スクリプトは Published 状態であり、現在の課題、イベントまたはフィールド変更、ワークフローアクション、タイマーのスケジュールコンテキスト、インバウンド HTTP リクエスト、呼び出し元、レスポンスに依存しない必要があります。

Run now では、現在のチームと実行管理者、変数とシークレット、および手動実行ポリシーで許可されたストレージ、OpenAPI、外部 HTTP、ログ機能を利用できます。バッチスクリプトでは、issue.search(...) または明示的な課題 ID で対象を選択してください。

確認ダイアログにはスクリプトと公開済みバージョンが表示され、本番データの変更と外部呼び出しのリスクが示されます。1 つのリクエストは 1 回だけ実行されます。ステータス、所要時間、操作、出力、エラーは実行ログに記録されます。Result Unknown は、スクリプトが実行された可能性はあるものの、最終的な記録状態を確認できないことを示します。再実行する前に、実行ログと業務データを確認してください。

タイマールールの間隔

項目ルール
単位Seconds、Minutes、Hours、Days
正の整数
範囲30 秒から 366 日
1 日の意味常に 24 時間
作成、再有効化、間隔変更サーバーの保存時刻に 1 回分の間隔を加算
名前だけを変更既存の Next run を維持
現在のスケジュールタイプ固定間隔

ルールカードの Last run と Next run はサーバーから返された値です。小数、Cron、自然言語スケジュール、「毎日何時」、タイムゾーン付きカレンダースケジュールはサポートされません。


ネイティブのスクリプトフィールド

ネイティブの浮動小数点数および Selection スクリプトフィールドは、private-full オンプレミスパッケージで利用できます。プロバイダースクリプトを公開した後、リソース → スクリプトフィールドで設定します。ネイティブフィールドの UUID は ONEScript が内部で管理します。

浮動小数点数

scriptedField スクリプトは有限数を 1 つ同期的に返します。

return 42.5

この L0 トリガーでは、ネットワークもストレージも使用できません。ルールを有効化するときにフィールド名を入力してください。作成者にネイティブフィールド UUID を検索させないでください。1 つのアプリインストールが所有するマニフェストで用意された浮動小数点数フィールドは 1 つです。ルールの編集ではそのフィールドを名前変更または再バインドし、追加の浮動小数点数フィールドは作成しません。

Selection の選択肢プロトコル

scriptedFieldOptions スクリプトは、プルダウンまたはプルダウン(複数)として設定されたネイティブの課題、プロジェクト、製品 Selection フィールドに選択肢を提供します。5 秒の制限がある読み取り専用 L1 です。ONES/OpenAPI の読み取りは許可されますが、課題、フィールド、ストレージ、変数、コメント、通知への書き込みはブロックされます。

ランタイムは selection.request を通じて、検索テキスト、ページング、選択済み ID、関連、ユーザー、フィールド、コンテキストを ONES から受け取ります。通常、作成者がこれらの値を直接解析する必要はありません。selection.options ヘルパーがキーワードフィルタリング、ページング、重複排除、選択済み ID の正確な解決、プラットフォームの { options, page_result } レスポンスを処理します。

selection.options.from(items, config?)

メモリ上の配列に使用します。文字列には個別の ID は不要です。

return selection.options.from(["High", "Medium", "Low"])

各文字列は識別子と表示値の両方になります。表示名を変更すると、保存された識別子も変わります。名前を変更する可能性がある選択肢では、安定した業務 / データソースキーを使用します。

return selection.options.from([
{ id: "level-high", value: "High" },
{ id: "level-medium", value: "Medium" }
])

作成者向けの標準形式は { id, value } です。

  • id は安定した業務 / データソースの識別子であり、ONES フィールド UUID ではありません。表示テキストが変わっても変更しないでください。
  • uuidid は同じ識別子の別名として使用できます。
  • valuenamelabeltitle は同じ表示テキストの別名として使用できます。
  • これらの別名に動作の違いはありません。ONEScript はプラットフォームの { uuid, value } 形式へ正規化します。
  • 安定した識別子のないオブジェクトは明示的に失敗します。ONEScript は配列位置、表示テキスト、ハッシュ、ランダム ID を生成しません。

カスタムオブジェクトプロパティでは、パスを一度設定します。

return selection.options.from(products, {
id: "productCode",
display: "{productCode} - {productName}",
searchBy: ["productCode", "productName"]
})

display にはプロパティパスまたは {token} テンプレートを指定できます。searchBy は既定で最終表示を検索します。同じ ID と表示の重複はまとめられ、1 つの ID に異なる表示がある場合は失敗します。

selection.options.fromIssues(config)

動的な課題の選択肢には、セマンティック課題検索アダプターを使用します。

return await selection.options.fromIssues({
where: {
issueType: "Requirement",
fields: { Priority: "Highest" }
}
})

where または matches のどちらか一方だけを指定します。issue.search が受け付ける同じセマンティック名を現在のチーム内で解決します。既定値は次のとおりです。

  • ID:課題 UUID。
  • 表示:{key} - {title}
  • 検索:課題キー、タイトル、最終表示。
  • ページング:ONES から要求されたページを自動的に検索して返す。
  • 選択済み ID の解決:現在のチーム内で UUID を正確に検索し、where / matches、キーワード、ページフィルターを再適用しない。
  • maxItems:省略可能な正の整数の業務ガード。超過した場合は明示的に失敗する。
  • 実行時間:選択肢スクリプトは最大 5 秒。タイムアウトまたは不完全なデータソースは明示的に失敗する。

省略可能なメンバーは selectmaxItemsdisplaysearchBy です。display{uuid}{key}{title}、通常のオブジェクトパス、{field:Field Name} をサポートします。テンプレートまたは検索で使用する名前付きフィールドは select に追加してください。

selection.options.fromProvider(config)

ページングされる外部 REST、ONES OpenAPI、ONESQL データソースに使用します。

return await selection.options.fromProvider({
search: async ({ keyword, offset, limit, relations, scope }) => {
const result = await loadCatalogPage({ keyword, offset, limit, relations, scope })
return { items: result.items, total: result.total }
},
resolve: async ({ uuids, relations, scope }) => {
return await loadCatalogItemsByIds(uuids, { relations, scope })
},
id: "id",
display: "{code} - {name}"
})

search は配列または { items, total } を返します。resolve は ONES が要求したすべての ID を返す必要があります。データソース固有の正確な ID 検索を ONEScript は推測できないため、両方のコールバックが必要です。scope には現在のフィールド UUID、ユーザー UUID、コンテキストが含まれます。ヘルパーが ONES プロトコルを処理し、プロバイダーコードはデータソースの検索と安定したデータソース識別子だけを担当します。


工数集計

taskPreAction スクリプト内の issue.worklog は、現在の課題の工数集計の変更不可スナップショットを公開します。

メンバー意味
spentHours現在の課題の登録工数
estimatedHours現在の課題の見積工数
remainingHours現在の課題の残り工数
hasSpent()spentHours > 0 のとき true
hasEstimate()estimatedHours > 0 のとき true
isOverEstimate()登録工数が見積工数を超えたとき true
varianceHoursspentHours - estimatedHours
progressPercent見積工数に対する登録工数の割合。見積工数がゼロの場合は null
totalEstimatedHoursプラットフォームが提供する見積工数の集計
totalRemainingHoursプラットフォームが提供する残り工数の集計

totalSpentHours はありません。ページングされた工数記録を一覧して合計することで推測しないでください。

if (
issue.status.changedFromTo("In Progress", "Done") &&
!issue.worklog.hasSpent()
) {
api.reject("Please register work before completing this issue.")
}

ドライランでは、シミュレートするフィールド変更とともに "issueKey": "PROJECT-123" のような表示されている課題キーを指定します。ONEScript は現在のチーム内でキーを解決します。ユーザーが context.taskUUID を検索する必要はありません。


セマンティックフィールド構文

読みやすい構文は、フィールド、ステータス、プロジェクト、課題タイプ、選択肢を表示名で解決します。名前と値は大文字小文字を区別し、完全一致します。User StoryUser story は別の値であり、ランタイムが小文字化したりあいまい一致したりすることは決してありません。

現在値のチェック

issue.project.is("Project Name")
issue.issueType.is("Requirement")
issue.status.is("In Review")
issue.statusCategory.is("in_progress")
issue.field("Priority").is("Highest")

issue.statusCategory は、3 つの固定されたカテゴリコードto_doin_progressdone — のいずれかにマッチします。これらは表示言語に関係なく、どのインスタンスでも同一です。(Done のようなローカライズされた表示名でもマッチしますが、そちらはインスタンス固有です。)対照的に、issue.status は表示名("In Review""Done")によって特定のワークフローステータスにマッチします。

フィールドの識別

  • issue.field("Field Name") は課題のフィールドメタデータに対して解決します。正確なフィールド表示名またはフィールド UUID が有効です。推測した名前、翻訳した名前、あいまいな名前は無効です。
  • 2 つのフィールドが同じ表示名を共有している場合、その参照はあいまいです。推測する代わりに、一意な名前またはフィールド UUID を指定してください。

フィールド値

.value.newValueアクセサーです。issue.field(...) に対して読み取るプロパティであり、呼び出すメソッドではありません。

  • issue.field("Priority").value — フィールドの現在の保存値。
  • issue.field("Planned end date").newValuetaskPreAction ガードにおける、これから入る(保留中の)値。そこでは、変更がまだ適用されていないため、.value はあえて変更前の状態のままになります。編集が設定しようとしている値を読むには、.newValue(または changedTo(...))を使ってください。taskPreAction の外では、.newValue に意味はありません。

型を意識した値

値は単なる文字列として扱われません。ONEScript はすべての値をフィールドのに応じて解釈・エンコードします。これは値が読み取られ、比較され、書き込まれるあらゆる場所に適用されます。.is(...).contains*(...) / .isExactly(...)、変更ヘルパー(.changedTo(...).changedFrom(...))、issue.update({...}) による書き込みは、すべて同じ型ルールを使います。値は自然で人間が理解できる形式(表示名、業務上の数値、日付文字列、ブール値)で指定すれば、ランタイムがそれを保存形式に変換し、比較時にはまた元に戻します。

フィールドタイプ値の指定方法(読み取り、比較、書き込み)
テキスト生の文字列 — "Test"
整数 / 浮動小数点業務上の数値 — 42(ランタイムが ONES のスケーリングを適用)
日付 / 時刻秒単位のタイムスタンプ、またはパース可能な日付/時刻文字列 — "2026-06-06"(秒に正規化される)
ブール値true / false
単一参照(選択肢、スプリント、ユーザー、プロジェクト、タスク、課題タイプ、ステータス)正確な表示名または ID。保存された ID に解決される
複数値(ユーザーリスト、複数選択肢、バージョン、プロジェクトリスト、部門)表示名または ID。ID 配列に解決される

解決が型を意識して行われるため、同じ値がマッチングでも書き込みでも機能します。例えば issue.field("Sprint").is("Sprint 12")issue.update({ Sprint: "Sprint 12" }) は、いずれも "Sprint 12" を保存された ID に解決します。表示値は大文字小文字を区別し、完全一致のままです。

複数値のマッチング

複数値フィールドでは、意図に合うヘルパーを選んでください。

issue.field("Tags").is("A")                 // contains this one value
issue.field("Tags").is(["A", "B"]) // exact set equality (order-independent)
issue.field("Tags").containsAll(["A", "B"]) // contains all of these
issue.field("Tags").containsAny(["A", "B"]) // contains at least one of these
issue.field("Tags").isExactly(["A", "B"]) // exactly this set

複数値の意図には containsAll / containsAny / isExactly を優先してください。読みやすく、正式な形式です。


変更ヘルパー

eventtaskActionDonetaskPreAction でのみ利用可能です(変更フィールド情報を持つトリガー)。

issue.anyFieldChanged()
issue.anyStatusChanged()
issue.status.changedTo("Done")
issue.statusCategory.changedTo("in_progress")
issue.statusCategory.changedFromTo("to_do", "in_progress")
issue.assignee.changedTo("Bob")
issue.assignee.changedFromTo("Alice", "Bob")
issue.field("Found in Production").changedTo("Yes")
issue.field("Priority").changedFrom("Low")
event.changedField("Status").isChanged()

updated イベントでのステータス関連ルールには、issue.anyStatusChanged() に加えて issue.status.changed* または issue.statusCategory.changed* を優先してください。taskPreAction ガードでは、フィールドの読み取りが変更前の状態を報告することに注意してください。.value.newValue についてはフィールド値を参照してください。


関連する課題と階層

現在の課題にリンクされた課題の状態を読み取ります。リンク/関連フィールド、または名前付きの親子階層によって参照します。フィールドを表示名で参照し、その後に量化子(all / any / none)と述語を使います。

issue.linkedIssues("Prerequisites").none.statusCategory.is("done")
issue.linkedIssues("Prerequisites").any.field("Priority").is("High")
issue.hierarchy("Upstream").any.field("Planned end date").isBefore("2026-08-01")
  • 量化子: all(すべてのリンクされた課題)、any(少なくとも 1 つ)、none(ゼロ)。リンクされた課題が 1 つもない場合、all / none は true、any は false になります。
  • 述語: status / statusCategory に加えて、フィールドヘルパー(iscontainscontainsAllcontainsAnyisExactly)、および日単位の日付順序比較 isAfter(value) / isBefore(value)。順序比較は、ONES が生成するあらゆる日付形式に対して日単位で行われます。値が欠けている場合や日付でない場合、述語は false になるため、未設定の日付が拒否を引き起こすことはありません。
  • issue.hierarchy("Name")linkedIssues と同じインターフェースで、プロダクトの概念に合わせて名付けられ、検証されます。階層でないフィールドや、解決できない表示名を指定すると、黙って何にもマッチしないのではなく、呼び出し箇所でスローします。
  • 集合のサイズ: .count はリンクされた課題の数です。.isEmpty は、集合が本当に空のときにのみ true になります。データが読み取れなかったり切り詰められたりした場合、.isEmptyfalse のままで、確認できない「空」を主張することは決してありません。これらを使って*「1 つもない」「どれもマッチしない」*を区別してください。none.<predicate>どちらの場合も true になるため、「前提課題がまったくない」ことをガードするには none ではなく .isEmpty(または .count === 0)を使ってください。
  • .list() (エスケープハッチ) — 量化子では表現できない反復処理のために、課題ごとのハンドルの読み取り専用配列を返します。各ハンドルは同じ status / statusCategory / field(name) 述語を公開しており、ネイティブの配列メソッド(.some.filter.length)を使えます。読みやすさのためには量化子を優先し、カスタムの反復処理が必要なときにだけ .list() を使ってください。
// Distinguish "no prerequisites" from "prerequisites not done"
if (issue.linkedIssues("Prerequisites").isEmpty) {
api.log("No prerequisites linked")
}
// Count the ones still open, using .list() + native array methods
const open = issue.linkedIssues("Prerequisites")
.list()
.filter(p => !p.statusCategory.is("done")).length
api.log(open + " prerequisite(s) still open")

正式な階層の日付ガード — 子の予定終了日が親のものより後になってはならない、という両方向のチェックです。

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.")
}
if (issue.hierarchy("Downstream").any.field("Planned end date").isAfter(next)) {
api.reject("A downstream (child) issue has a later planned end date; adjust it first.")
}
}

ホストがリンクされた課題を読み取れない場合(一時的な障害、またはファンアウト上限を超えた場合)、述語はスローし、その実行は自動的な拒否ではなく失敗した実行として記録されます。フェイルクローズするには、ルールを try { ... } catch (e) { api.reject("Cannot verify prerequisites.") } で囲んでください。


書き込みヘルパー

書き込み可能なトリガーtaskActionDoneeventtimer)でのみ利用可能です。api.reject(...) は例外で、taskPreAction に属します。

issue.update({ Priority: "Highest" })          // canonical batch field update
issue.transitTo("Done") // workflow-based status change
issue.addComment("Handled by ONEScript.") // add a plain-text comment
api.reject("Reason shown to the user.") // taskPreAction only

api.reject(...) の理由にシークレットを含めないでください。解決済みシークレットと完全一致する値が誤って使用された場合、プラットフォームの reject_reason とホスト決定ログには [REDACTED] と表示されます。エンコード、ハッシュ化、分割、一部抽出、その他の変換後の値は保護されません。

課題ステータスの遷移

課題ステータスは通常の書き込み可能なフィールドではありません。現在の課題を正確な対象ステータスへ移動するには、次を優先します。

issue.transitTo("Done")

対象は、大文字と小文字を区別する正確なステータス表示名またはステータス ID です。ONEScript は現在の課題で実行可能なワークフローを検索し、対象に一致する唯一のアクションを実行します。部分一致や大文字と小文字を区別しない一致は使用せず、複数のアクションが同じステータスに到達する場合も任意に選択しません。

省略可能な第 2 引数にはワークフローフォームデータを指定します。課題やワークフローを指定するものではありません。

issue.transitTo("Done", {
fields: {
Resolution: "Fixed"
},
comment: [
{ contentType: 1, text: "Completed by ONEScript." }
],
resources: ["attachment-id"],
timeEstimated: { hours: 4 },
timeSpent: [
{
owner: "user-uuid",
startTime: 1785340800,
hours: 1,
description: "Final verification"
}
]
})
  • fieldsissue.update(...) と同じ表示名および型を意識した値解決を使用します。
  • comment は配列で、contentType は正の整数、text は文字列です。resources には既存の添付ファイル ID を指定します。
  • timeEstimated.hourstimeSpent.startTimetimeSpent.hours は整数です。各登録工数行には担当者 UUID も必要です。
  • issueIDtaskUUIDworkflowID、Raw fieldValues を渡さないでください。現在の課題とワークフローの検索は ONEScript が管理します。
  • 課題がすでに対象ステータスの場合、遷移は何もしません。実行可能なアクションがない場合はエラー、対象へ到達する実行可能なアクションが複数ある場合は AMBIGUOUS_WORKFLOW になります。
  • 実行可能なワークフローの読み取りは安全に再試行できます。ワークフロー実行リクエストは最大 1 回送信され、不明な転送結果の後に再試行されることはありません。
  • taskPreAction は入れ子のワークフローを開始できません。送信中のアクションをブロックするには api.reject(...) を使用するか、event またはアクション後スクリプトでステータスを変更します。
  • ドライランでは実行可能なワークフローを読み取って結果をプレビューできますが、ワークフロー実行リクエストは送信しません。

既存のセマンティック更新も互換性を維持します。issue.update(...)Status が含まれる場合、ONEScript は同じワークフローパスで処理し、他のフィールドをそのアクションとともに送信します。

issue.update({
Status: "Done",
Resolution: "Fixed"
})

明示的な課題ステータス変更には issue.transitTo(...)、ステータスとフィールドをまとめて送信する場合は issue.update(...) を使用します。Status Category は派生値であり、書き込めません。Raw openapi.issue.update ペイロードは field005 を書き込めません。既知のワークフロー ID を意図的に選択する高度なスクリプトは、そのアクションが現在実行可能であることを確認した後にのみ openapi.workflow.transit を使用できます。

メール通知

公式の ONES 通知チャネルを通じてメールを送信します。書き込み可能な非同期トリガー(timereventtaskActionDone)のみ、かつオンプレミスのデプロイのみです。SaaS 対応ビルドは、送信する代わりに、サポート対象外である旨の結果を明示的にログに記録します。

api.notify({
channel: "email", // required; only "email" is supported
recipients: ["<userUUID>"], // ONES user UUIDs (never emails or names), max 100
title: "Overdue issues need attention",
message: "This issue has stayed in the current stage for over 3 days.",
issue: context.taskUUID // optional; the host builds the email link from it
})

配信は自動的に再試行されません。通知ごとの結果は実行ログで確認してください。リッチなメールには、columns(テーブルのヘッダー)と items(課題ごとに 1 行、最大 20 件)を追加します。各リンクはホストが構築し、生の URL 値は拒否されます。

コメントとメンション

issue.addComment({
text: "The status changed, please check",
mentions: [issue.assignee.mention()]
})

issue.addComment(...) はサポートされています。メンション.mention() / .mentions())は文書化されていますが、再検証待ちです。依拠する前に、ドライラン / 実行ログで検証してください。

カスタムメンバーフィールドには、issue.field("Reviewer").mention()(単一ユーザー)または issue.field("Reviewers").mentions()(複数ユーザー)を使ってください。コメントテキストは text に保持し、フィールドヘルパーでメンションを供給できる場合は生のユーザー UUID を読み取らないでください。

遷移のブロック: ガードスクリプトでは、変更をブロックするのは api.reject(...) だけです。スローしたり、タイムアウトしたり、ポリシー制限に達したりしたスクリプトは診断のためにログに記録されますが、遷移をブロックしません。そのため、api.reject(...) を意図的に呼び出すか、何もしないかのいずれかのガードを書いてください。信頼できるスコープが利用できず、有効なスコープ付きガードが適用される可能性がある場合は、ガード選択が別途フェイルクローズし、スクリプトを実行しません。


データのクエリ

issue.search(...) は、課題を業務上の意味で見つけるための正式な方法です。ネットワークが許可されている場所(L1 トリガー)で利用できます。専用のクエリ UI はなく、クエリはスクリプト内で行います。

const issues = await issue.search({
where: {
issueType: "Requirement",
fields: { Priority: "Highest" }
},
select: ["Estimated Hours"], // read named fields onto each row (unknown names throw)
limit: 100
})
api.log("Matched issues: " + issues.length)

limit の既定値は 50 で、1 から 100 までの整数でなければなりません。1 回の呼び出しで返す課題数の上限を指定します。offset は、先頭から指定した件数をスキップするために使用します。

const issues = await issue.search({
where: { issueType: "Requirement" },
offset: 100,
limit: 50
})

複数ページを連続して処理する場合は、結果の読み取り専用 pageInfo を使用します。現在のページの pageInfo.endCursor を次の呼び出しの cursor に渡します。

let cursor = ""

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

for (const item of issues) {
api.log(item.key + " - " + item.title)
}

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

cursor と 0 以外の offset を同時に指定しないでください。ページング結果に重複、件数超過、不完全なメタデータ、または前進しない Cursor がある場合、クエリは明示的に失敗します。

issue.search({ where, select, offset, limit, cursor }) は行にバインドされたセマンティック課題を返すため、各結果は現在値ヘルパー、issue.assignee.mention()issue.update(...)issue.addComment(...)issue.transitTo(...) をサポートします。これらはその結果の課題に固定されます。条件オブジェクトは projectissueType(または type)、statusstatusCategoryassignee、および名前付きの fields をサポートします。where またはその別表記 matches のいずれか一方だけを指定してください。

スケジュールされたクエリ。 タイマールールは、issue.search をスケジュールに従って実行できます。例えば、毎朝、各担当者に期限超過の課題についてメールを送るといった使い方です。書き込みヘルパーapi.notify を参照してください。

生の ONESQL は、issue.search で表現できない条件(日付範囲など)のための高度なエスケープハッチとしてのみ使ってください。単数形の issue テーブルとフィールド UUID を使い、セマンティック課題メソッドを持たないプレーンなデータ行を返します。

const rows = await api.queryIssues({
query: "SELECT uuid, field001 FROM issue WHERE v$cursor > '' LIMIT 1000, 20",
variables: []
})

値は引用符付きのリテラルとしてインライン化してください。$1 形式の位置パラメーター variables依存しないでください(一部のデプロイではこのパラメーターを無視し、リテラルのテキスト $1 にマッチさせ、エラーなく 0 行を返します)。


ランタイムの状態と変数

const token = vars.get("WEBHOOK_TOKEN")                 // Resources → Variables
const cursor = await api.storage.get("lastCursor") // get: read-only L1 OK
await api.storage.set("lastCursor", { issue: context.taskUUID }) // set/delete: write-capable L1
api.log("Cursor saved")

api.storage は ONEScript 自身のランタイム状態です。(これは Hosted-App のオブジェクト/エンティティストレージではありません。それは 1.1 では公開されていません。)

シークレットタイプの変数では、ONEScript は実行ログ、スクリプト出力、記録された効果ペイロード内の完全一致する平文をマスクします。同じ実行中に作成または初めて解決されたシークレットも含まれます。完全一致マスクは、エンコード、ハッシュ化、分割、一部抽出、その他の変換後の値には適用されません。シークレットを読める作成者は信頼できる認証情報の利用者として扱い、シークレットをログ、戻り値、コメント、通知、永続化データに含めないでください。


外部 HTTP と OpenAPI

外部 HTTP

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

ルール:

  • https URL のみ受け付けます。通常の HTTP と URL ユーザー情報は DNS の前に拒否されます。
  • L1 のネットワーク可能なトリガーのみ(taskPreActionscriptedField は不可)。
  • method を省略した場合、body があるリクエストは POST、ないリクエストは GET を使用します。
  • GETHEADOPTIONS は読み取りポリシーを使用し、その他のメソッドには書き込み可能なトリガーが必要です。
  • リクエストとレスポンスのボディは 512 KB、リクエストヘッダーは 32 KB に制限されます。
  • timeoutMs を指定する場合は有限の数値でなければなりません。文字列、NaN、無限値は DNS の前に拒否されます。
  • ランタイムは localhost、プライベート、リンクローカル / クラウドメタデータ、CGNAT、ドキュメント / ベンチマーク、マルチキャスト / 予約済み IPv4 範囲、すべての IPv6 宛先、ローカル専用ホスト名をブロックします。デュアルスタックホストは検証済みのパブリック IPv4 に固定され、IPv6 専用の宛先はサポートされません。デプロイで許可リストによる追加制限を行う場合があります。
  • HostContent-LengthTransfer-EncodingConnectionKeep-AliveTETrailerUpgrade、プロキシ認証ヘッダーなど、トランスポートが制御するヘッダーを設定しないでください。無効なヘッダー名や CRLF / NUL を含む値は拒否されます。
  • トークンは vars.get(...) を通じて読み取ってください。トークン、認証ヘッダー、シークレットのペイロードは決してログに出力しないでください
  • アダプターを使ってください。生の fetch は決して使わないでください。

OpenAPI ヘルパー(制限あり)

カタログに基づくヘルパーは、名前で ONES OpenAPI を呼び出します。名前空間には openapi.issue.*openapi.workflow.transitopenapi.issueComment.*openapi.worklog.*openapi.wiki.*openapi.account.*openapi.project.*openapi.testcaseLibrary.* が含まれます。

const response = await openapi.issue.create({
query: { teamID: context.teamUUID },
body: {
projectUUID: context.projectUUID,
issueTypeUUID: context.issueTypeUUID,
summary: "Follow-up from ONEScript"
}
})
api.log("Created issue status: " + response.statusCode)

openapi.request(...) / api.fetchOpenAPI(...) はエスケープハッチですが、それでもトリガーポリシーと操作チェックに従います。OpenAPI のパスやヘルパー名を勝手に作り出さないでください。

Raw OpenAPI パスは /openapi 名前空間内にある必要があります。ランタイムはポリシーチェックの前に、パーセントエンコード、スラッシュ、バックスラッシュ、末尾区切り、ドットセグメントを正規化します。既知のブロック対象操作と未知の変更パスはすべてフェイルクローズします。未知の安全な読み取りは、正規化された /openapi 名前空間内でのみ許可されます。

注意すべき現在の制限:

  • Copilot ヘルパー — 検証済みプロファイルではサービスレベルでブロックされています。
  • サマリー工数ログヘルパー — 一致するチーム工数ログプロファイルでゲートされています。
  • Hosted-App のオブジェクト/エンティティストレージ — 公開されていません。api.storage を使ってください。

インバウンド REST エンドポイント

インバウンドエンドポイントは、外部システムが任意の公開済みスクリプトの正確な最新バージョンを HTTP 経由で呼び出せるようにします。ScriptRunner の「カスタム REST エンドポイント」に相当します。保存されているスクリプトタイプは httpEndpoint である必要はありません。エンドポイント実行時に、リクエスト、認証済み呼び出し元、レスポンスの各サーフェスが提供されます。REST エンドポイントタブで、公開済みスクリプト、slug、認証モード、runAs モードを選択します。POST /hooks/<slug> で到達します(POST のみ)。

requestcontext.request としても利用可能)でリクエストを読み取ります

フィールド意味
slugマッチしたエンドポイントの slug
method / pathHTTP メソッドとパス
queryクエリ文字列のパラメーター
headers業務ヘッダーのみ — 認証/シークレットヘッダーはスクリプトが見る前に取り除かれます
bodyボディが JSON の場合は解析済みオブジェクト、そうでなければ生の文字列
rawBodyプラットフォームが配信したボディから正規化して再構築された文字列。JSON の場合、呼び出し元の元のプロトコルバイトではない

api.response.send(...)レスポンスを送ります。そうしない場合、スクリプトの通常の出力が 200 の JSON ボディになります。

const order = context.request.body
api.response.send({
status: 201,
headers: { "Content-Type": "application/json" },
body: { received: order.id }
})

失敗状態(タイムアウト、ポリシー拒否、拒否)は安全なステータスコードにマッピングされ、スクリプトの出力を漏らしません。

認証(エンドポイントごとに設定):

モード認証方法
ones検証済み ONES OAuth2 トークン。必要なスコープとユーザー / 組織 / クライアント許可リストをサポートし、呼び出し元はエンドポイントのチームに所属している必要がある
tokenエンドポイント専用シークレットに保存される、生成された共有 Bearer トークン
hmac生成されたエンドポイント専用シークレットを使用するリクエスト署名。タイムスタンプ許容範囲付き

Token/HMAC 認証情報は生成時に一度だけ表示され、通常のスクリプト変数では置き換えられません。同じモードで編集すると認証情報を再利用し、認証モードを変更するとローテーションし、ones への切り替えまたはエンドポイント削除で認証情報を削除します。スクリプトは自身のエンドポイント認証情報を読み取れません。HMAC 署名とタイムスタンプは専用ヘッダーでのみ受け付けます。

新しい HMAC JSON クライアントは次を送信します。

X-ONEScript-Signature-Version: onescript-json-v1
X-ONEScript-Timestamp: <timestamp>
X-ONEScript-Signature: sha256=<lowercase HMAC-SHA256 hex>
Content-Type: application/json

署名入力は次の内容を UTF-8 でエンコードしたものです。

onescript-json-v1
<timestamp>
<RFC 8785 canonical JSON>

署名入力のタイムスタンプは、タイムスタンプヘッダーと完全に一致する必要があります。JSON オブジェクトのプロパティは UTF-16 コード単位で再帰的に並べ替えられ、配列は順序を維持し、プリミティブは ECMAScript JSON シリアル化を使用します。I-JSON を送信し、重複オブジェクトキー、有限でない数値、単独の Unicode サロゲートを避けてください。業務値、タイムスタンプ、署名バージョンを変更すると、スクリプト実行前に認証が失敗します。

X-ONEScript-Signature-Version のないリクエストでは、既存クライアント向けにのみ過去の再構築ボディアルゴリズムを保持します。新しい連携では使用しないでください。元の Raw JSON バイトにしか署名できない、または ONEScript 署名バージョンヘッダーを送信できない第三者プロバイダーは HMAC モードと互換性がありません。

REST エンドポイントはプロジェクトまたは課題タイプのスコープをサポートしません。空でないスコープ設定は、暗黙に無視せず拒否されます。

ones 認証の既定値は呼び出し元として実行です。管理者として実行するには、少なくとも 1 つの明示的な呼び出し元スコープ、ユーザー、組織、クライアント制約が必要です。アプリ ID がネットワーク、書き込み、ストレージを提供します。遅延された課題、コメント、通知の効果は、成功して拒否されていない実行の後、成功レスポンスを返す前にのみコミットされます。コミットがゼロで直接ホスト I/O がないと証明できた場合だけ予約を解放します。部分的または不明なコミット結果ではキーを予約したままにし、同じ冪等キーは 409 を返します。

呼び出し元として実行。 このモードは ones 認証でのみ利用できます。Raw OpenAPI リクエストと別名、生成された openapi.* ヘルパー、メタデータ、ONESQL、issue.search(...)issue.update(...)issue.set(...)issue.addComment(...)issue.transitTo(...) は、現在のリクエスト元の ONES ID と権限で実行されます。ID または権限が不足している場合は明示的に失敗し、管理者へフォールバックしません。呼び出し元の認証情報はホスト内に保持され、スクリプトコードやログには公開されません。

Hosted API、チーム変数の管理、api.notify(...) は呼び出し元 OpenAPI 操作ではないため、引き続き利用できません。

外部 HTTP と api.storage / api.scriptStorage は、呼び出し元モードでも通常のエンドポイント L1 アダプターです。ネットワーク、書き込み、チーム、スクリプト分離ポリシーに従い、ONES の呼び出し元として実行したり、なりすましたりしません。

依存関係とコミット期限。 エンドポイント設定、シークレット、公開済みスクリプト、ランタイム設定の読み取り期限は 3 秒、ONES トークンイントロスペクションとチームメンバーシップのチェックは 5 秒、冪等性の読み取りと予約は 1.5 秒です。実行前のタイムアウトは、安全な 503 を返し、スクリプトを実行せず、入口と認証済みリクエストの容量を解放します。予約タイムアウトは不明な結果として扱います。ONEScript はキーを無条件に解放しないため、遅れて完了した予約により同じキーが 409 を返す場合がありますが、他のキーは続行できます。ベストエフォートの実行ログ、配信ログ、安全な予約解放の書き込み期限は 1.5 秒で、業務レスポンスを変更したり、リクエスト容量を占有し続けたりしません。

スクリプトが正常に実行された後、各遅延効果のトランスポート呼び出しには、合計 10 秒の効果コミット予算内で 5 秒の期限があります。絶対予算は、元の呼び出しだけでなく認可更新と再試行も対象にします。いずれかのホップがタイムアウトした後、ONEScript は後続ホップ、再試行、フォールバック、次の効果を開始しません。コミット結果が不明なため、エンドポイントは一般的な 500 を返し、冪等キーを保持し、リクエスト容量を解放します。特に、最初の呼び出しがすでに配信した可能性があるため、タイムアウトしたメール送信は第 2 の通知チャネルにフォールバックしません。

リクエストとレスポンスの制限。 インバウンド URL は 4096 バイト、リクエストヘッダーは 100 件かつ合計 32 KB、リクエストボディは 512 KB に制限されます。実行タイムアウトは 10 秒、レスポンスボディは 256 KB です。超過レスポンスは安全な 500 を返し、切り捨てません。api.response.send(...)status は 200 から 599 の整数でなければなりません。レスポンスヘッダーは最大 64 件、合計 32 KB です。ヘッダー名は有効でなければならず、値には CRLF または NUL を含められません。Set-CookieContent-Length、ホップバイホップヘッダー、その他のトランスポート制御ヘッダーは拒否されます。無効なレスポンスメタデータは転送されず、エンドポイントを失敗させます。


サンドボックスで禁止されているもの

スクリプト検証は、動的なエスケープハッチとホストアクセスを拒否します。

evalFunctionrequire、動的な import、モジュールローダー、processglobalThisBuffer、ファイルシステム(fs)、子プロセスアクセス、そして生の fetch です。また、サンドボックスグローバルの可能性が高いタイポや、サポートされていないヘルパーシグネチャも、公開やドライランの前にフラグを立てます。


実行容量

スクリプト実行は共有された上限付きプールで動作します。ONES インスタンスごと、およびチームごとに、同時実行数と待機数が制限されます。

  • プールに空きがある場合、追加の実行は短時間待機してから通常どおり実行されます。
  • 待機キューが満杯の場合、新しい実行は無期限に待機せず直ちに失敗します。出力も効果も適用されず、失敗は実行ログに記録されます。
  • 待機はチーム間で公平に共有されるため、1 つのチームのバックログが別のチームを枯渇させることはありません。

容量不足はスクリプトの不具合ではありません。発生した場合は、トリガーの実行頻度を下げるか、長時間の処理を複数のスケジュール実行に分割してください。


サポートされていない機能

ONEScript 1.1 は次をサポートしません

  • フォームが開く前にネイティブの ONES 遷移/アクションボタンを非表示にすること(taskPreAction は送信時に拒否できますが、ボタンの早期の表示制御はできません)。
  • 完全な Jira Behaviours(フォーム入力中の任意のネイティブフィールドの非表示/表示/名前変更/説明変更)。
  • SaaS のネイティブスクリプトフィールド(現在はプライベートデプロイ向けに限定)。
  • フィールドグループの値連動(groupFieldOnChange)とフィールドグループの送信検証(groupFieldValidate)。
  • カスタム JQL / ネイティブ ONESQL 関数の注入。
  • 任意の Node.js、ファイルシステム、プロセス、パッケージインポート、生の HTTP、または制限のないランタイムアクセス。
  • L0 トリガー(taskPreActionscriptedField)でのネットワークまたはストレージ(OpenAPI の読み取りを含む)。Selection 選択肢プロバイダーは、別の読み取り専用 L1 scriptedFieldOptions トリガーを使用します。
  • Hosted-App のオブジェクト/エンティティストレージへの書き込み。OAuth トークンまたはアプリ認可の管理エンドポイント。
  • ユーザーのなりすまし / 別ユーザーとしての実行。

これらが Jira/ScriptRunner からどのようにマッピングされるかについては、Atlassian からの移行を参照してください。


バージョン管理

このリファレンスは ONEScript 1.1(ビルド 1.1.3)を対象としています。アップグレードする際は、次を再確認してください。

  • トリガーの一覧とポリシーマトリクス、
  • ヘルパーの可用性(特に OpenAPI の名前空間とメンション)、
  • サポートされていないもののリスト。

変更履歴は早期プレビュー以降維持されています(リソース → 変更履歴を参照してください)。