আপনার ট্র্যাকের জন্য Continuous Integration (CI) সেট আপ করা খুবই গুরুত্বপূর্ণ, কারণ এটি ভুল ধরতে সাহায্য করে।
Exercism-এর রিপোজিটরিগুলো (ট্র্যাক রিপোজিটরিসহ) তাদের CI চালাতে GitHub Actions ব্যবহার করে। GitHub Actions নির্ভর করে ওয়ার্কফ্লো-এর উপর, যেগুলো কোনো নির্দিষ্ট ঘটনা ঘটলে (যেমন একটি কমিট পুশ করা) স্বয়ংক্রিয়ভাবে চালানোর স্ক্রিপ্ট নির্ধারণ করে। GitHub Actions ওয়ার্কফ্লো সম্পর্কে আরও জানতে, ওয়ার্কফ্লো ডকুমেন্টেশন দেখুন।
ট্র্যাকগুলোতে আগে থেকেই বেশ কিছু ওয়ার্কফ্লো ইনস্টল করা থাকে, যেগুলোর বেশিরভাগই আপনার পরিবর্তন করা উচিত নয় (এগুলোকে শেয়ার্ড ওয়ার্কফ্লো বলা হয়)।
তবে একটি ওয়ার্কফ্লো আছে যা আপনার পরিবর্তন করা উচিত, সেটি হলো test.yml ওয়ার্কফ্লো।
test.yml ওয়ার্কফ্লোর লক্ষ্য হলো ট্র্যাকের অনুশীলনীগুলো সঠিক অবস্থায় আছে কি না, তা যাচাই করা।
main ব্রাঞ্চে বা কোনো পুল রিকোয়েস্টের ব্রাঞ্চে পুশ করা হলে এই ওয়ার্কফ্লো স্বয়ংক্রিয়ভাবে চালু হওয়ার জন্য সেট আপ করা থাকে (GitHub Actions-এর পরিভাষায়: triggered হয়)।
ওয়ার্কফ্লোর নিজের খুব বেশি কাজ থাকা উচিত নয়, শুধু এগুলো ছাড়া:
যেমন বলা হয়েছে, অনুশীলনীগুলো একটি স্ক্রিপ্ট দিয়ে যাচাই করা হয়, সেটি হলো bin/verify-exercises (bash) স্ক্রিপ্ট।
এই স্ক্রিপ্টটি প্রায় তৈরি হয়ে গেছে, এবং এটি নিচের কাজগুলো করে:
unskip_tests ফাংশন কল করে, যেখানে আপনি আপনার টেস্ট ফাইলের টেস্টগুলো আনস্কিপ করতে পারেন (ঐচ্ছিক)run_tests ফাংশন কল করে, যেখানে আপনার টেস্টগুলো রান করা উচিত (আবশ্যক)শুধু run_tests আর unskip_tests ফাংশন দুটোই আপনার তৈরি করা প্রয়োজন।
আপনার ট্র্যাক যদি টেস্ট স্কিপ করা সাপোর্ট করে, তবে কোনো অনুশীলনীর example/exemplar সমাধান যাচাই করার সময় যেন কোনো টেস্ট স্কিপ না হয়, তা নিশ্চিত করতে হবে। সাধারণত, ট্র্যাকগুলো টেস্ট "আনস্কিপ" করার দুটি উপায় সাপোর্ট করে:
test.skip-কে test-এ বদলে দেওয়া।SKIP_TESTS=false সেট করা।টেস্ট স্কিপ করা যদি ফাইল-ভিত্তিক হয় (উপরে উল্লেখিত প্রথম উপায়), তবে টেস্ট ফাইলগুলো পরিবর্তন করতে unskip_tests ফাংশনটি সম্পাদনা করুন (বিদ্যমান কোডটি ইতিমধ্যেই টেস্ট ফাইলগুলোর উপর লুপ করা সামলায়)।
unskip_test ফাংশনটি একটি অনুশীলনী ডিরেক্টরির একটি কপিতে চলে, তাই আপনার ইচ্ছেমতো ফাইলগুলো পরিবর্তন করতে পারেন।
Arturo ট্র্যাকের bin/verify-exercises file টেস্ট ফাইলের ভেতরের টেস্টগুলো আনস্কিপ করতে sed ব্যবহার করে:
unskip_tests() {
jq -r '.files.test[]' .meta/config.json | while read -r test_file; do
sed -i 's/test.skip/test/g' "${test_file}"
done
}
টেস্ট আনস্কিপ করতে যদি কোনো এনভায়রনমেন্ট ভ্যারিয়েবল সেট করা প্রয়োজন হয়, তবে সেটি যেন run_tests ফাংশনে সেট করা থাকে, তা নিশ্চিত করুন।
run_tests ফাংশনটি একটি অনুশীলনীর টেস্ট রান করার দায়িত্বে থাকে।
ফাংশনটি কল করা হলে, example/exemplar ফাইলগুলো ইতিমধ্যেই (স্টাব) সমাধান ফাইলে কপি হয়ে যাবে, তাই টেস্টগুলো রান করতে শুধু সঠিক কমান্ডটি কল করলেই হবে।
সব টেস্ট পাস হলে ফাংশনটিকে exit code হিসেবে শূন্য রিটার্ন করতে হবে, অন্যথায় শূন্য নয় এমন একটি exit code রিটার্ন করতে হবে।
run_tests ফাংশনটি একটি অনুশীলনী ডিরেক্টরির একটি কপিতে চলে, তাই আপনার ইচ্ছেমতো ফাইলগুলো পরিবর্তন করতে পারেন।
verify exercises স্ক্রিপ্টের ডিফল্ট বিকল্প হলো ভাষার টুলিং (SDK/বাইনারি/ইত্যাদি) ব্যবহার করা, যা বেশিরভাগ ট্র্যাক ব্যবহার করে। প্রতিটি ট্র্যাকের টেস্ট রান করার নিজস্ব উপায় থাকবে, তবে সাধারণত এটি শুধু একটি একক কমান্ড।
Arturo ট্র্যাকের bin/verify-exercises file run_tests ফাংশনটি পরিবর্তন করে যাতে এটি টেস্ট ফাইলে সরাসরি arturo কমান্ড কল করে:
run_tests() {
arturo tester.art
}
দ্বিতীয় বিকল্প হলো ট্র্যাকের টেস্ট রানার চালিয়ে অনুশীলনীগুলো যাচাই করা। এটি অবশ্যই নির্ভর করে ট্র্যাকের একটি কার্যকর টেস্ট রানার থাকার উপর।
আপনার ট্র্যাকের যদি এখনো টেস্ট রানার না থাকে, তবে আপনি দুটির একটি করতে পারেন:
ডিফল্ট bin/verify-exercises স্ক্রিপ্টে নিচের পরিবর্তনগুলো আনতে হবে:
docker কমান্ডটি পাওয়া যায় কি না, তা যাচাই করাdocker run ব্যবহার করাresults.json ফাইলে সব টেস্ট পাসের কথা বোঝা যাচ্ছে কি না, তা যাচাই করতে jq ব্যবহার করাunskip_test ফাংশনটি এবং সেই ফাংশনের কলটি সরিয়ে ফেলাএই পদ্ধতির মূল সুবিধা হলো, এটি প্রোডাকশনে (ওয়েবসাইটে) টেস্ট কীভাবে রান হয় তা সবচেয়ে ভালোভাবে অনুকরণ করে। এই পদ্ধতিতে, CI-তে পাস করা কোনো কিছু প্রোডাকশনে ব্যর্থ হওয়ার সম্ভাবনা কম থাকে। এই পদ্ধতির অসুবিধা হলো, Docker ইমেজ পুল করতে হওয়া এবং Docker-এর বাড়তি ওভারহেডের কারণে এটি সাধারণত ধীর হয়।
Unison ট্র্যাকের bin/verify-exercises file docker কমান্ডটিও ইনস্টল করা আছে কি না, তা যাচাই করার চেক যোগ করে:
required_tool docker
তারপর এটি ট্র্যাকের টেস্ট রানার ইমেজ পুল করে:
docker pull exercism/unison-test-runner
এরপর এটি run_tests ফাংশনটি পরিবর্তন করে যাতে docker run দিয়ে বর্তমান অনুশীলনীতে (যা ওয়ার্কিং ডিরেক্টরিতে আছে) টেস্ট রানার চালানো হয়, তারপর সঠিক স্ট্যাটাস যাচাই করতে একটি jq কমান্ড চালানো হয়:
run_tests() {
local slug
slug="${1}"
docker run \
--rm \
--network none \
--mount type=bind,src="${PWD}",dst=/solution \
--mount type=bind,src="${PWD}",dst=/output \
--tmpfs /tmp:rw \
exercism/unison-test-runner "${slug}" "/solution" "/output"
jq -e '.status == "pass"' "${PWD}/results.json" >/dev/null 2>&1
}
সবশেষে, আমাদের run_tests কমান্ডের কলটি পরিবর্তন করতে হবে, কারণ এখন এটি slug চেয়ে থাকে:
run_tests "${slug}"
এখন যেহেতু verify-exercises স্ক্রিপ্ট শেষ, সময় হয়েছে test.yml ওয়ার্কফ্লোটি চূড়ান্ত করার।
এটি কীভাবে করবেন, তা নির্ভর করে verify-exercises স্ক্রিপ্টের বাস্তবায়নে কোন বিকল্প বেছে নেওয়া হয়েছে তার উপর।
verify-exercises স্ক্রিপ্ট যদি সরাসরি ভাষার টুলিং ব্যবহার করে, তবে টেস্ট ওয়ার্কফ্লোকে ইনস্টল করতে হবে:
এটি হয়ে গেলে, verify-exercises প্রত্যাশামতো কাজ করবে, আর আপনি সফলভাবে CI সেট আপ করেছেন!
একটি উদাহরণের জন্য, Arturo ট্র্যাকের test.yml ওয়ার্কফ্লো দেখুন:
name: Test
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
ci:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install libgtk-3-dev libwebkit2gtk-4.0-dev libmpfr-dev
- name: Install Arturo
run: bin/install-arturo
env:
GH_TOKEN: ${{ github.token }}
- name: Verify all exercises
run: bin/verify-exercises
দ্বিতীয় বিকল্প হলো ট্র্যাকের টেস্ট রানার চালিয়ে অনুশীলনীগুলো যাচাই করা। এই বিকল্পের জন্য দুটি শর্ত পূরণ হতে হবে:
verify-exercises স্ক্রিপ্ট একটি অনুশীলনীর টেস্ট চালাতে টেস্ট রানার Docker ইমেজ ব্যবহার করেআপনার ট্র্যাকের যদি এখনো টেস্ট রানার না থাকে, তবে আপনি দুটির একটি করতে পারেন:
এই পদ্ধতির কয়েকটি সুবিধা আছে:
প্রধান অসুবিধা হলো, Docker ইমেজ পুল করতে হওয়া এবং Docker-এর বাড়তি ওভারহেডের কারণে এটি সম্ভবত ধীর হয়।
টেস্ট রানার Docker ইমেজ পুল করার কয়েকটি উপায় আছে:
verify-exercises ফাইলের ভেতরেই ইমেজটি ডাউনলোড করা।
এই পদ্ধতি নিয়েছে Unison ট্র্যাক।তাহলে কোন পদ্ধতি ব্যবহার করবেন?
আমরা সুপারিশ করি অন্ততপক্ষে ১ নম্বর বিকল্পটি বাস্তবায়ন করতে, যাতে verify-exercises স্ক্রিপ্টটি স্ট্যান্ডঅ্যালোন হয়।
আপনার ইমেজ যদি বিশেষভাবে বড় হয়, তবে ৩ নম্বর বিকল্পটিও বাস্তবায়ন করা উপকারী হতে পারে, যা বিল্ড করা Docker ইমেজ GitHub Actions ক্যাশে জমা রাখবে।
তখন পরবর্তী রানগুলো ইমেজ ডাউনলোড না করে শুধু ক্যাশ থেকে পড়তে পারবে, যা পারফরম্যান্সের জন্য ভালো হতে পারে (নিশ্চিত হতে মেপে দেখুন)।
তৃতীয় একটি বিকল্প উপায় হলো আগের দুটি বিকল্পের মিশ্রণ।
এখানেও আমরা টেস্ট রানার Docker ইমেজ ব্যবহার করছি, তবে এবার verify-exercises স্ক্রিপ্টটি সেই Docker ইমেজের ভেতরেই চালাই।
এই বিকল্প চালু করতে, ওয়ার্কফ্লোর container-কে টেস্ট রানারে সেট করতে হবে:
container:
image: exercism/vimscript-test-runner
তারপর আমরা ডিপেন্ডেন্সি ও টুলিং ইনস্টলের ধাপগুলো বাদ দিতে পারি (কারণ সেগুলো টেস্ট রানার Docker ইমেজের ভেতরে ইনস্টল করা থাকবে) এবং bin/verify-exercises স্ক্রিপ্ট চালানো শুরু করতে পারি।
vimscript ট্র্যাকের test.yml ওয়ার্কফ্লো এই বিকল্পটি ব্যবহার করে:
name: Verify Exercises
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
jobs:
ci:
runs-on: ubuntu-24.04
container:
image: exercism/vimscript-test-runner
steps:
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
- name: Verify all exercises
run: bin/verify-exercises