高度なクリーンアップ
Server ライセンスのサポートは 2024 年 2 月 15 日をもって終了しました。代わりの選択肢についてはこちらをご確認ください。
基本的なクリーンアップが完了したら、より高度なクリーンアップ操作に進むことができます。高度なクリーンアップを完了するには、いくつかのスクリプトを実行する必要があります。
追加の必須クリーンアップ プロセス
推奨頻度: 年に 1 回
必要なスキル: 高度な Jira 管理者スキル
注: 次のスクリプトで使用されている API は、お使いの Jira バージョンでは動作しない場合があります。ご利用の Jira バージョンと互換性のある正しい API を使用していることをご確認ください。Jira の各バージョンで使用できる Java API の完全なリストについては、開発者向けドキュメントをご参照ください。
タスク 1: 未使用または非アクティブなワークフローを削除します
クリーンアップする対象を特定するにはどうすればよいですか?
Admin Toolbox for Jira を使用して、非アクティブなワークフローをすばやく見つけることができます。
クリーンアップの方法を教えてください
非アクティブなワークフローまたは未使用のワークフローとそのスキームをシステムから削除します。これを行う前に、バリデーターと事後操作がカスタム フィールドで構成されていないことを確認してください。より少ないワークフローで、より保守とサポートが容易になります。詳細については、「ワークフローで作業する」をご覧ください。
非アクティブなワークフローとワークフロー スキームを削除するには、ScriptRunner アプリを取得して次のスクリプトを実行することをお勧めします。
これらの機能リンクやサードパーティ製プラグインは、当社のサポート対象外ですのでご注意ください
未使用のワークフロー スキームから開始します。すべての非アクティブなワークフロー スキームを削除するには、以下のスクリプトを実行します。
import com.atlassian.jira.component.ComponentAccessor
def schemeManager = ComponentAccessor.workflowSchemeManager
def sb = new StringBuffer()
sb.append("Deleted inactive workflow schemes:\n")
schemeManager.schemeObjects.each {
try{
if(schemeManager.getProjectsUsing(schemeManager.getWorkflowSchemeObj(it.id)).size() == 0) {
schemeManager.deleteScheme(it.id)
sb.append("${it.name}\n")
}
}
catch(Exception e) {
//noop
sb.append("Error: " + e + "\n");
}
}
return "<pre>" + sb.toString() + "<pre>"
未使用または非アクティブなワークフローを削除するには、次のスクリプトを実行します。
import com.atlassian.jira.component.ComponentAccessor
def workflowManager = ComponentAccessor.workflowManager
def schemeManager = ComponentAccessor.workflowSchemeManager
def sb = new StringBuffer()
sb.append("Deleted inactive workflows:\n")
workflowManager.workflows.each {
if(!it.systemWorkflow) {
def schemes = schemeManager.getSchemesForWorkflow(it)
if (schemes.size() == 0) {
workflowManager.deleteWorkflow(it)
sb.append("${it.name}\n")
}
}
}
return "<pre>" + sb.toString() + "<pre>"
タスク 2: 未使用の画面と画面スキームを削除する
クリーンアップする対象を特定するにはどうすればよいですか?
ScriptRunner アプリは、未使用の画面やスクリーン スキームを特定して削除するのに役立ちます。さまざまな Jira アーティファクト間の関係を視覚化するのに役立つ Config Insights for Jira。
既定の画面スキームと既定の画面を削除しないことをお勧めします。
クリーンアップの方法を教えてください
プロジェクトが関連付けられていないすべての課題タイプ画面スキームを削除します。
import com.atlassian.jira.component.ComponentAccessor
def schemeManager = ComponentAccessor.issueTypeScreenSchemeManager
def defaultScheme = schemeManager.defaultScheme;
def sb = new StringBuffer()
sb.append("Deleted issue type screen schemes with no associated projects:\n")
schemeManager.issueTypeScreenSchemes.each {
try{
if(it == defaultScheme) {
//do not delete the default scheme
return;
}
if(it.projects.size() == 0) {
//remove any associations with screen schemes
schemeManager.removeIssueTypeSchemeEntities(it);
//remove the issue type screen scheme
schemeManager.removeIssueTypeScreenScheme(it);
sb.append("${it.name}\n")
}
}
catch(Exception e) {
//noop
sb.append("Error: " + e + "\n");
}
}
return "<pre>" + sb.toString() + "<pre>"
2. 課題タイプ画面スキームに使用されていない、または削除された課題タイプ画面スキームでしか使用されていない画面スキームを削除します。
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.fields.screen.FieldScreenSchemeManager
def fssm = ComponentAccessor.getComponent(FieldScreenSchemeManager.class)
def itssm = ComponentAccessor.issueTypeScreenSchemeManager
def sb = new StringBuffer()
sb.append("Deleted screen schemes with no associated issue type screen schemes:\n")
fssm.fieldScreenSchemes.each { fss ->
try {
def itssCollection = itssm.getIssueTypeScreenSchemes(fss);
// find field screen schemes that are still associated with deleted issues type screen schemes
def allDeleted = true;
itssCollection.each { itss ->
if(itss != null) {
allDeleted = false;
return;
}
}
//remove field screen schemes with no (valid) associated issue type screen schemes
if(itssCollection.size() == 0 || allDeleted == true) {
//remove association to any screens
fssm.removeFieldSchemeItems(fss);
//remove field screen scheme
fssm.removeFieldScreenScheme(fss);
sb.append("${fss.name}\n");
}
}
catch(Exception e) {
//noop
sb.append("Error: " + e + "\n");
}
}
return "<pre>" + sb.toString() + "<pre>"
3. 未使用の画面を削除します。Jira のバージョンによってコードが異なりますのでご注意ください。
Jira 8.20 以降を実行している場合は、以下のコードを実行します。
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.fields.screen.FieldScreenFactory
import com.atlassian.jira.issue.fields.screen.FieldScreenManager
import com.atlassian.jira.issue.fields.screen.FieldScreenSchemeManager
import com.atlassian.jira.bc.issue.fields.screen.FieldScreenService
import com.atlassian.jira.web.action.admin.issuefields.screens.ViewFieldScreens
import com.atlassian.jira.workflow.WorkflowManager
import com.atlassian.webresource.api.assembler.PageBuilderService
def fieldScreenManager = ComponentAccessor.getFieldScreenManager()
def fieldScreenFactory = ComponentAccessor.getComponent(FieldScreenFactory.class)
def fieldScreenSchemeManager = ComponentAccessor.getComponent(FieldScreenSchemeManager.class)
def fieldScreenService = ComponentAccessor.getComponent(FieldScreenService.class)
def workflowManager = ComponentAccessor.getWorkflowManager()
def authenticationContext = ComponentAccessor.getJiraAuthenticationContext()
def pageBuilderService = ComponentAccessor.getComponent(PageBuilderService.class)
def viewFieldScreens = new ViewFieldScreens(fieldScreenManager, fieldScreenFactory, fieldScreenSchemeManager, fieldScreenService,
workflowManager, authenticationContext, pageBuilderService)
// use StringBuffer to spit out log to screen for ScriptRunner Console
def sb = new StringBuffer()
sb.append("Delete unused screens:\n");
fieldScreenManager.getFieldScreens().each {
fieldScreen ->
//find all screens with no (or only null/previously deleted) screen schemes or workflows
def allEmptyOrNull = true;
viewFieldScreens.getFieldScreenSchemes(fieldScreen).each {
fieldScreenScheme ->
if (fieldScreenScheme != null) {
allEmptyOrNull = false;
return;
}
}
if (!allEmptyOrNull) {
return;
}
viewFieldScreens.getWorkflows(fieldScreen).each {
workflow ->
if (workflow != null) {
allEmptyOrNull = false;
return;
}
}
if (allEmptyOrNull) {
fieldScreenManager.removeFieldScreen(fieldScreen.getId())
sb.append("${fieldScreen.getName()}\n")
}
}
return "<pre>" + sb.toString() + "<pre>"
Jira 8.20 より前のバージョンを実行している場合は、以下のコードを実行します。
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.fields.screen.FieldScreenFactory
import com.atlassian.jira.issue.fields.screen.FieldScreenManager
import com.atlassian.jira.issue.fields.screen.FieldScreenSchemeManager
import com.atlassian.jira.web.action.admin.issuefields.screens.ViewFieldScreens
import com.atlassian.jira.workflow.WorkflowManager
def fieldScreenManager = ComponentAccessor.getFieldScreenManager()
def fieldScreenFactory = ComponentAccessor.getComponent(FieldScreenFactory.class)
def fieldScreenSchemeManager = ComponentAccessor.getComponent(FieldScreenSchemeManager.class)
def workflowManager = ComponentAccessor.getWorkflowManager()
def viewFieldScreens = new ViewFieldScreens(fieldScreenManager, fieldScreenFactory, fieldScreenSchemeManager, workflowManager)
// use StringBuffer to spit out log to screen for ScriptRunner Console
def sb = new StringBuffer()
sb.append("Delete unused screens:\n");
fieldScreenManager.getFieldScreens().each { fieldScreen ->
//find all screens with no (or only null/previously deleted) screen schemes or workflows
def allEmptyOrNull = true;
viewFieldScreens.getFieldScreenSchemes(fieldScreen).each { fieldScreenScheme ->
if(fieldScreenScheme != null) {
allEmptyOrNull = false;
return;
}
}
if(!allEmptyOrNull) {
return;
}
viewFieldScreens.getWorkflows(fieldScreen).each { workflow ->
if(workflow != null) {
allEmptyOrNull = false;
return;
}
}
if(allEmptyOrNull) {
fieldScreenManager.removeFieldScreen(fieldScreen.getId())
sb.append("${fieldScreen.getName()}\n")
}
}
return "<pre>" + sb.toString() + "<pre>"
タスク 3: 解決策をレビューする
Jira の解決状況はグローバルに共有されているため、可能な限り統合することで、煩雑さが軽減されます。
クリーンアップする対象を特定するにはどうすればよいですか?
"Resolution = 'whatever'" などの JQL クエリを実行して、特定の解決策を使用している問題 (もしあれば) を見つけます。
解決策によって JQL クエリをグループ化する課題統計ガジェットを作成することもできます。ガジェットの詳細については、「ダッシュボード ガジェットの使用」を参照してください。
クリーンアップの方法を教えてください
管理パネルの [解決策] ページで、削除する解決策の [削除] をクリックします。Jira は、現在その解決策がある問題の数を教えてくれます。また、それらの課題については、リストから別の解決策を選択するよう求められます。
タスク 4: フィールド設定をクリーンアップする
フィールド設定の目的は、各プロジェクト (および Issuetype) で使用できるフィールドを Jira に指示することです。フィールドがどの画面にも存在しない場合でも、再インデックス プロセスにおいて考慮されます。
デフォルトでは、Jira は、新しく作成されたすべてのカスタム フィールドを使用可能なすべてのフィールド設定に追加します。そのため、カスタム フィールドが多いと、パフォーマンスが低下する可能性があります。
クリーンアップする対象を特定するにはどうすればよいですか?
このタスクでは、何かを削除する必要はありませんが、カスタム フィールドを非表示にして、プロジェクトに必要なフィールドだけを有効にしてください。これは、かなり安全なクリーンアップ方法であるといえます。
クリーンアップの方法を教えてください
フィールドに関連付けられていない「空の」フィールド設定 (FC) を作成します。テンプレートとして使用し、この設定にすべてのカスタム フィールドを追加し、それらを無効にします。新しいプロジェクトを作成するときは、これらのプロジェクト (または課題タイプ) で使用する目的のフィールドのみを有効にできます。
次に、ScriptRunner アプリケーションを使用して、次のスクリプトを実行します。これにより、特定のフィールド設定のすべてのカスタム フィールドが非表示になります。それらは、そのフィールド設定を使用するすべてのプロジェクトで非表示になり、編集できなくなります。
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.fields.layout.field.FieldLayoutManager
import com.atlassian.jira.issue.fields.layout.field.EditableFieldLayout
import com.atlassian.jira.issue.fields.layout.field.FieldLayoutItem
FieldLayoutManager fieldConfigurationManager = ComponentAccessor.getComponent(FieldLayoutManager)
EditableFieldLayout fieldConfiguration = fieldConfigurationManager.getEditableFieldLayout(18000L)
List<FieldLayoutItem> items = fieldConfiguration.getFieldLayoutItems()
items.each {
try {
fieldConfiguration.hide(it)
} catch (ignored) {}
}
fieldConfigurationManager.storeEditableFieldLayout(fieldConfiguration)
タスク 5: アプリを監査する
未使用のアプリをアンインストールすると、Jira が不要な RAM を使用できないようにし、マーケットプレースのコストを抑え、新しいバージョンにアップグレードする時間を節約できます。
クリーンアップする対象を特定するにはどうすればよいですか?
残念ながら、アプリの動作はそれぞれ大きく異なり、1 つのアプローチですべてのアプリがどのように使用されているかを把握することは不可能です。
最適な方法は、各アプリの使用状況を手動で確認することです。
クリーンアップの方法を教えてください
使用率の低いアプリや、テスト環境で疑いがもたれたアプリを無効にし、結果を観察します。
自動化の方法を教えてください
各タスクについて、新しいエンティティが作成されているかを監視し (詳細監査ログはここで役立ちます)、定期的なレビューを実行することをお勧めします。