ScriptRunnerAutomationJira

جابه‌جایی Issue بین پروژه‌ها در جیرا با ScriptRunner: چرا اسکریپت‌های رایج خطا می‌دهند

محمد مهیار احمدی۸ دقیقه مطالعه

جابه‌جایی یک Issue بین دو پروژه از طریق رابط کاربری ساده است: یک ویزارد چندمرحله‌ای که کلید Issue را عوض می‌کند، Workflow را مهاجرت می‌دهد، فیلدها را نگاشت می‌کند و پیوست‌ها را جابه‌جا می‌کند. مشکل وقتی شروع می‌شود که بخواهید همین کار را برنامه‌ای انجام دهید — مثلاً برای صدها Issue یا داخل یک قانون خودکار.

اگر دنبالش گشته باشید، احتمالاً به تردهای Atlassian Community رسیده‌اید و اسکریپتی برداشته‌اید که یا NullPointerException می‌دهد یا اصلاً کامپایل نمی‌شود. دلیلش را در ادامه می‌گویم، چون فهمیدنش از خود اسکریپت مهم‌تر است.

چرا اسکریپت‌های اینترنتی می‌شکنند

دو دلیل مشخص دارد و هر دو ریشهٔ یکسانی دارند: این اسکریپت‌ها به کلاس‌های داخلی Jira وابسته‌اند که بخشی از API عمومی نیستند.

  • امضای سازنده عوض شده. کلاس داخلی در نسخهٔ ۸ سه پارامتر می‌گرفت و در نسخهٔ ۹ چهارتا. اسکریپتی که برای نسخهٔ قدیمی نوشته شده، روی نسخهٔ شما کامپایل نمی‌شود.
  • وابستگی‌ای که تزریق نشده. بعضی از این کلاس‌ها انتظار دارند در بستر یک درخواست وب ساخته شوند. وقتی از Script Console صدایشان می‌زنید، بخشی از بستر وجود ندارد و اولین دسترسی به آن، NullPointerException می‌دهد.

چرا نمی‌شود ساده فقط پروژه را عوض کرد

سؤال طبیعی این است: چرا فیلد پروژه را عوض نکنیم و تمام؟ چون جابه‌جایی واقعی شش کار جدا دارد و فیلد پروژه فقط یکی از آن‌هاست:

کاری که باید انجام شوداگر نشود چه می‌شود
تولید کلید جدید و ثبت کلید قدیمیلینک‌های قدیمی می‌شکنند
مهاجرت WorkflowIssue در وضعیتی می‌ماند که در Workflow مقصد وجود ندارد
نگاشت Issue Typeنوعی که در پروژهٔ مقصد نیست
نگاشت وضعیت‌هاوضعیت نامعتبر — Issue از همهٔ گزارش‌ها می‌افتد
فیلدهای اجباری مقصدIssue ناقص ذخیره می‌شود
جابه‌جایی فایل پیوست روی دیسکپیوست‌ها ناپدید می‌شوند

به‌روزرسانی مستقیم پایگاه داده هم گزینه نیست: ایندکس Lucene به‌روز نمی‌شود، کش‌ها نمی‌دانند، و پشتیبانی اطلسین چنین محیطی را پشتیبانی نمی‌کند.

روشی که پایدار است

به‌جای بازسازی این شش مرحله، همان مسیری را طی کنید که ویزارد داخلی طی می‌کند. ویزارد Move Issue پشت صحنه دو مرحله دارد: مرحله‌ای که فیلدها و نگاشت‌ها را می‌گیرد، و مرحله‌ای که تایید و اجرا می‌کند. اگر همان‌ها را به ترتیب صدا بزنید، همهٔ منطق داخلی — از جمله مهاجرت Workflow و جابه‌جایی پیوست — رایگان به دست می‌آید.

مزیت اصلی‌اش این است که وقتی اطلسین منطق داخلی را عوض می‌کند، شما به‌طور خودکار همان تغییر را می‌گیرید — به‌جای اینکه اسکریپت شما با فرض قدیمی بماند.

قبل از اجرا: پنج چیزی که باید چک کنید

  1. وضعیت فعلی Issue در Workflow مقصد وجود دارد؟ اگر نه، نگاشت وضعیت لازم است وگرنه Issue در وضعیت نامعتبر گیر می‌کند.
  2. Issue Type در پروژهٔ مقصد تعریف شده؟ اگر نه، باید نوع را هم نگاشت کنید.
  3. فیلدهای اجباری مقصد مقدار دارند؟ فیلدی که در پروژهٔ مبدأ اختیاری بوده ممکن است در مقصد اجباری باشد.
  4. Issue زیرکار (Sub-task) دارد؟ زیرکارها باید با والد جابه‌جا شوند، وگرنه یتیم می‌مانند.
  5. بکاپ گرفته‌اید؟ جابه‌جایی برگشت‌پذیر نیست. برگرداندنش یک جابه‌جایی دوم است، نه یک undo.

کاری که حتماً باید بکنید: تست دسته‌ای کوچک

هیچ‌وقت اولین اجرا را روی صدها Issue نزنید. ترتیب درست:

۱. یک Issue آزمایشی روی محیط تست
۲. همان Issue را کامل بررسی کنید:
     کلید جدید ساخته شد؟
     وضعیت معتبر است؟
     پیوست‌ها باز می‌شوند؟
     تاریخچه سالم است؟
     لینک‌ها و ارجاع‌ها کار می‌کنند؟
۳. پنج Issue با شرایط متفاوت (با زیرکار، با پیوست، بسته‌شده)
۴. تازه بعد: دستهٔ کامل، خارج از ساعت کاری

و لاگ بگیرید. حداقل کلید قدیمی، کلید جدید و نتیجهٔ هر جابه‌جایی را در فایلی بنویسید. اگر چیزی خراب شد، بدون این فهرست نمی‌دانید کدام Issueها را باید بررسی کنید.

کِی اصلاً این کار را نکنید

گاهی درخواست جابه‌جایی دسته‌ای، علامت یک مشکل ساختاری است نه یک نیاز واقعی. اگر مدام Issueها در پروژهٔ اشتباه ساخته می‌شوند، ریشه معمولاً یکی از این‌هاست:

  • پروژه‌ها بر اساس چیزی تقسیم شده‌اند که مدام عوض می‌شود (مثلاً تیم، به‌جای محصول)
  • کاربر موقع ساخت Issue نمی‌فهمد کدام پروژه درست است
  • یک Component یا فیلد می‌توانست جای یک پروژهٔ کامل را بگیرد

در این حالت‌ها، اصلاح ساختار پروژه‌ها یک‌بار برای همیشه جواب می‌دهد و اسکریپت جابه‌جایی فقط علامت را می‌پوشاند. این همان بحثی است که در طراحی Workflow در Jira دربارهٔ ساختار درست باز کرده‌ام.

جمع‌بندی

جابه‌جایی برنامه‌ای Issue شدنی است، ولی به API عمومی و پایدار متکی نیست. روش درست، فراخوانی همان مسیر داخلی ویزارد است — نه بازسازی منطقش. و چون به نسخه حساس است، بعد از هر ارتقای بزرگ باید دوباره تست شود.

اگر تعداد Issueها زیاد است یا محیطتان Data Center است، این کار را خارج از ساعت کاری و با بکاپ تازه انجام دهید. Automation و حذف کار دستی دقیقاً همین دست کارهاست.

سؤالی دربارهٔ همین موضوع دارید؟

بپرسید. اگر جوابش کوتاه باشد همان‌جا می‌گویم و اگر نیاز به بررسی داشته باشد، می‌گویم چه چیزی لازم است.

پرسیدن در واتساپ

خواندن بعدی

درخواست جلسهتماس