এই ডকুমেন্টে ব্যাখ্যা করা হয়েছে কীভাবে GitHub Actions (GHA) ব্যবহার করে একটি Exercism প্রোগ্রামিং ট্র্যাকের জন্য Continuous Integration (CI) ওয়ার্কফ্লো সেট আপ করা যায়। এতে আপনি নিজের দ্রুত, নির্ভরযোগ্য এবং মজবুত CI ওয়ার্কফ্লো তৈরিতে ব্যবহার করতে পারেন এমন সেরা চর্চা ও উদাহরণ দেওয়া হয়েছে। এই ফোল্ডারের GHA ওয়ার্কফ্লোগুলো যেকোনো CI-এর সাথে কাজ করার জন্য মানিয়ে নেওয়া যায়, কারণ মূল কাঠামো একই থাকবে।
এতে থাকবে:
এই ওয়ার্কফ্লো ফাইলগুলোর একটি উদাহরণ বাস্তবায়ন exercism/javascript-এ পাওয়া যাবে।
ডকুমেন্টের বাকি অংশটি ওয়ার্কফ্লোগুলো কীভাবে কাজ করে তা ব্যাখ্যা করার জন্য সাজানো হয়েছে। যদি আপনার তাড়া থাকে এবং PR স্ক্রিপ্ট অপটিমাইজ না করেই শুধু Travis বা Circle থেকে GHA-তে যেতে চান, তাহলে Travis থেকে মাইগ্রেশন নিয়ে আমাদের ~১০ মিনিটের গাইড দেখুন।
আপনার রিপোজিটরির কনটেন্ট সঠিক আছে কিনা তা যাচাই করার জন্য সুপারিশকৃত অ্যাকশনগুলো নিচে দেওয়া হলো:
config.json যাচাই করতে configlet লিন্টিং
v3-এ নতুন ফাইল দরকার; এটা হয়তো পরে configlet-এ চলে যাবে)ট্র্যাক-নির্দিষ্ট অ্যাকশনও থাকতে পারে। যেমন:
আর হয়তো আপনি আরও কিছু কোয়ালিটি অব লাইফ যাচাই চাইবেন, যেমন:
প্রতিটি অ্যাকশনের জন্য ভাবুন সেটি কত ঘন ঘন চালানো উচিত।
configlet লিন্টিং এতটাই গুরুত্বপূর্ণ (কারণ config.json নষ্ট হলে একটি ট্র্যাক ভেঙে যেতে পারে) যে এটি সম্ভবত সবসময় চালানো উচিত, কিন্তু প্রতি কমিটে একবার চালালেই যথেষ্ট।যে অ্যাকশনগুলো চালানো উচিত, সেগুলো লোকালিও পাওয়া গেলে খুবই সহায়ক হতে পারে। এর মানে হলো যে স্ক্রিপ্টগুলো আসল কাজটি করে, সেগুলোও হাতে চালানো যায়। এটা অর্জন করতে ওয়ার্কফ্লো ফাইলের ভেতরে অ্যাকশন ইনলাইন করবেন না, বরং একটি আলাদা স্ক্রিপ্ট তৈরি করুন। উদাহরণস্বরূপ, স্টাব যাচাই করা ওয়ার্কফ্লো ফাইলের ভেতরেই সম্পূর্ণভাবে লেখা যেতে পারে, কিন্তু এখানে সুপারিশ হলো এর বদলে একটি নতুন এক্সিকিউটেবল স্ক্রিপ্ট scripts/ci-check তৈরি করা।
"কিন্তু কমান্ডটি তো খুব ছোট, যেমন
eslint . --ext ts --ext tsx।"যখন এই কমান্ডটি আপডেট করতে হবে, তখন এটিকে ডকুমেন্টেশনের সব জায়গায়, ওয়ার্কফ্লো ফাইলগুলোতে এবং মেইনটেইনারদের মনে আপডেট করতে হবে। এটা একটি স্ক্রিপ্টে বের করে আনলে সব সমস্যার সমাধান হয়। তাছাড়া একটি ওয়ার্কফ্লো ফাইল পড়া খুবই ভয়ংকর হতে পারে।
scripts/pr এবং scripts/pr-check স্ক্রিপ্টগুলো (দেখুন টেমপ্লেট) একাধিক আর্গুমেন্ট নিয়ে চালানো হয়, এই PR-এ পরিবর্তিত বা যোগ করা প্রতিটি ফাইলের জন্য একটি করে। উদাহরণস্বরূপ, যদি two-fer আপডেট করা হয়, একটি কল দেখতে এরকম হতে পারে:
scripts/pr exercises/two-fer/README.md exercises/two-fer/.meta/example.ext
পরিবর্তিত ফাইলের উপর নয়, বরং পরিবর্তিত অনুশীলনীর উপর যেকোনো অ্যাকশন চালানোর সুপারিশ করা হয়। কারণ একটি ফাইল পরিবর্তন করলে সম্ভবত পুরো অনুশীলনীর জন্য পরিবর্তন ঘটে (ভাবুন: কনফিগারেশন, প্যাকেজ)।
তৈরি নন? / জটিল?
এই অপটিমাইজেশন বাস্তবায়নের আগে এটি নিরাপদে উপেক্ষা করা যেতে পারে! মাইগ্রেশন গাইডে পরবর্তী কোনো ধাপে এটি যোগ করার ইঙ্গিত আছে। যদি ইনপুট আর্গুমেন্টগুলো উপেক্ষা করা হয়, সব যাচাই সব অনুশীলনীর উপর চলবে। এটি সম্পূর্ণ ঠিক আছে। শুধু বেশি সময় লাগবে।
ট্র্যাকে যদি একটি একক "টপ-লেভেল" ডিপেন্ডেন্সি ফাইল এবং/অথবা অন্য কনফিগারেশন ফাইল থাকে, তাহলে একটি সঠিকতা ধাপ যোগ করুন (যেটি একটি scripts/sync বা bin/sync-এর পাশাপাশি থাকে, যা সব কনফিগারেশন ফাইল সব অনুশীলনীতে কপি করে), যা নিশ্চিত করে যে টপ-লেভেল/বেস ফাইলগুলো অনুশীলনী ডিরেক্টরিতে কপি করা ফাইলের মতোই। এখন ডিপেন্ডেন্সি আপডেট করা যায়, পুরো রিপোজিটরিতে সিঙ্ক করা যায়, এবং আমরা নিশ্চিত করতে পারি যে সব অনুশীলনীর একই কনফিগারেশন আছে।
এটি অর্জনের একটি কমন উপায় হলো একটি চেকসাম ব্যবহার করা। Ubuntu (এবং আরও কিছু Linux ডিস্ট্রিবিউশন) sha1sum নামের একটি টুলের সাথে আসে, কিন্তু কনফিগারেশন ফাইলকে চেকসাম মানে হ্যাশ বা কমিয়ে আনতে যে কোনো পদ্ধতি (md5, sha1, crc32) ব্যবহার করলেই হবে:
$ sha1sum README.md
cd58091c5043bf21f00d39ff1740d8b2976deeff *README.md
যদি ট্র্যাক GitHub token বা অন্য সিক্রেটে অ্যাক্সেস প্রয়োজন হয় এমন অতিরিক্ত ওয়ার্কফ্লো ব্যবহার করে, তাহলে ওয়ার্কফ্লোতে ব্যবহৃত সব অ্যাকশন একটি নির্দিষ্ট কমিটে পিন করার সেরা চর্চা। বিস্তারিত জানতে দেখুন GitHub-এর সিকিউরিটি হার্ডেনিং গাইড।
উদাহরণস্বরূপ:
- uses: julia-actions/setup-julia@v1
+ uses: julia-actions/setup-julia@d26d1111976eae5f00db04f0515ab744ec9cd79e # 1.3.1
যদি টুলিং-এ ডিপেন্ডেন্সি ম্যানেজমেন্টের জন্য লকফাইল থাকে, তাহলে সেটি রিপোজিটরিতে চেক-ইন করার কথা ভাবুন এবং ওয়ার্কফ্লো ফাইলের ভেতরে একটি "frozen lockfile" ব্যবহার করুন। উদাহরণস্বরূপ: npm ci, yarn install --frozen-lockfile এবং bundle install --frozen। এটি নিশ্চিত করে যে ডিপেন্ডেন্সি পরিবর্তনের সময় লকফাইল হালনাগাদ থাকে এবং ক্ষতিকর প্যাকেজ ঢুকে পড়া প্রতিরোধ করে।
এই ডিরেক্টরিতে কমপক্ষে নিচের টেমপ্লেটগুলো আছে:
configlet.yml: এই ওয়ার্কফ্লো সর্বশেষ configlet বাইনারি ফেচ করে এই রিপোজিটরি লিন্ট করবে। প্রতি কমিটে চালিত হয়। PR-এর ক্ষেত্রে আসল কমিটে এবং একটি "মার্জের পরের" tree-তে চালিত হয়।ci.yml: এই ওয়ার্কফ্লো শুধু main ব্রাঞ্চে চালিত হয়, প্রতিটি কমিটে একবার।
pr.ci.yml: এই ওয়ার্কফ্লো শুধু PR-এ চালিত হয়, প্রতিটি কমিটে একবার।
যেসব ওয়ার্কফ্লো pr- নয় সেগুলো workflow_dispatch দিয়েও ট্রিগার করা যায়।
প্রতিটি ফাইলের顶部ে কোন "script"গুলো থাকা উচিত তা তালিকাবদ্ধ আছে। যদি এগুলো বাইনারি হিসেবে চান, scripts/xxx-এর বদলে bin/xxx লিখুন। কিছু টুলিং আবশ্যক করে যে বাইনারিগুলো একটি bin ফোল্ডারের ভেতরে থাকুক।
scripts/ci: একটি স্ক্রিপ্ট যা উদাহরণ সলিউশন ব্যবহার করে টেস্টের বিরুদ্ধে সব অনুশীলনী বিল্ড ও টেস্ট করবেscripts/ci-check: একটি স্ক্রিপ্ট যা সব অনুশীলনী লিন্ট করবে, এবং ঐচ্ছিকভাবে স্টাব, কনফিগারেশনের সঠিকতা ইত্যাদি যাচাই করবেscripts/pr: scripts/ci-এর মতোই, কিন্তু ইনপুট হিসেবে দেওয়া পাথ থেকে যে অনুশীলনীগুলো পাওয়া যায় শুধু সেগুলোর উপর চালাবেscripts/pr-check: scripts/ci-check-এর মতোই, কিন্তু ইনপুট হিসেবে দেওয়া পাথ থেকে যে ফাইল বা অনুশীলনীগুলো পাওয়া যায় শুধু সেগুলোর উপর চালাবেযদি কোনো সমস্যায় পড়েন বা কেউ আপনার ওয়ার্কফ্লো রিভিউ করে দিক এমন চান, তাহলে @exercism/github-actions টিমকে পিং করুন।
টপ-লেভেল ফাইল পরিবর্তন করেছেন যা সব অনুশীলনীর উপর একটি CI রান ট্রিগার করা উচিত
লেখার সময়ে, pr.ci.yml শুধু "extension" টেস্টিং সমর্থন করে। আদর্শভাবে এটিকে এমনভাবে আপডেট করা হবে যাতে নির্দিষ্ট ফাইল পরিবর্তিত হলে (যেমন টেস্ট চালানোর বাইনারি) এটি সবসময় ট্রিগার হয়। তবে এই পরিবর্তনগুলো প্রায়শই ঘন ঘন হয় না এবং মেইনটেইনাররাই করে থাকেন, তাই ci.yml main-এ সবকিছুর জন্য সবসময় চালিত হওয়াটা সম্ভবত যথেষ্ট নিরাপদ।
Windows-এ scripts/xxx ফাইল তৈরি করেছেন এবং এখন তা {other OS}-এ কাজ করছে না
ডিফল্টভাবে, Windows-এ তৈরি ফাইলগুলোতে তাদের এক্সিকিউটেবল হওয়া সম্পর্কে git-index-এ মেটাডেটা এমবেড করা থাকে না, কারণ Windows-এ পারমিশনের মডেল আলাদা। Git, ডিফল্টভাবে, git-index মেটাডেটা ব্যবহার করে নির্ধারণ করে ফাইলটি POSIX-ভিত্তিক সিস্টেমে এক্সিকিউটেবল হওয়া উচিত কিনা, এবং তাই scripts/xxx ফাইলটিকে এক্সিকিউটেবল করে না।
git update-index --chmod=+x scripts/xxx
git commit -m "Make scripts/xxx executable"