কম্পিউটার টিউটোরিয়াল

গিটহাব ইভেন্ট ডেটা পাবলিশ করুন অ্যাকশনস (Actions) ও পেজেস (Pages) দিয়ে: ধাপে ধাপে গাইড

গিটহাবে কাজ করা টিমগুলো কোলাবোরেশন (collaboration) করার জন্য ইভেন্ট ডেটা (event data)-র ওপর নির্ভর করে। ইস্যু (issues), পুল রিকোয়েস্ট (pull requests), এবং কমেন্ট (comments) হিসেবে রেকর্ড করা ডেটা প্রজেক্ট বুঝতে অপরিহার্য হয়।

গিটহাব অ্যাকশনস (GitHub Actions)-র জেনারেল অভেইলেবিলিটি (general availability) দিয়ে, আমাদের প্রোগ্রাম্যাটিক্যালি (programmatically) গিটহাব ইভেন্ট ডেটা অ্যাক্সেস ও প্রিজার্ভ (preserve) করার সুযোগ পেলাম আমাদের রিপোজিটরিতে। ডেটাকেই রিপোজিটরির অংশ করে তোলা গিটহাবের বাইরে সেটি প্রিজার্ভ করার একটি উপায়। এছাড়া এটি আমাদের দেয় ডেটাটি একটি ফ্রন্ট-ফেসিং ওয়েবসাইটে ফিচার (feature) করার ক্ষমতা, যেন গিটহাব পেজেস (GitHub Pages) দিয়ে।

এবং, যদি আপনি আমার মত হন, তবে আপনি গিটহাব ইস্যু কমেন্টগুলোকে একটি চমৎকার ৯০-এর দশকের গেস্টবুক (guestbook) পেজে রূপান্তর করতে পারেন।

ব্যবহার যেকোনো হোক, মূল কনসেপ্টগুলো একই। আমরা অ্যাকশনস (Actions) ব্যবহার করতে পারি ইভেন্ট ডেটা অ্যাক্সেস, প্রিজার্ভ, এবং ডিসপ্লে করার জন্য - শুধু একটা ওয়ার্কফ্লো ফাইল (workflow file) দিয়ে। প্রক্রিয়াটি ইলাস্ট্রেট (illustrate) করতে, আমি আপনাকে আমার গেস্টবুক চমকে রাখার ওয়ার্কফ্লো কোড (workflow code) দিয়ে যাব।

গিটহাব অ্যাকশনস (GitHub Actions) সম্পর্কে একটি ইন্ট্রোডাক্টরি লুক (introductory look) পেতে, যেন ওয়ার্কফ্লো কীভাবে ট্রিগার (trigger) হয়, দেখুন "A lightweight, tool-agnostic CI/CD flow with GitHub Actions"।

গিটহাব ইভেন্ট ডেটা অ্যাক্সেস করা

একটি অ্যাকশন ওয়ার্কফ্লো (Action workflow) একটি এনভায়রনমেন্টে (environment) রান হয় কিছু ডিফল্ট এনভায়রনমেন্ট ভেরিয়েবলস (environment variables) সহ। এখানে অনেক সুবিধাজনক ইনফরমেশন উপলব্ধ, ইভেন্ট ডেটা সহ। ইভেন্ট ডেটা অ্যাক্সেস করার সবচেয়ে কমপ্লিট (complete) উপায় হচ্ছে $GITHUB_EVENT_PATH ভেরিয়েবল ব্যবহার করা, যা কমপ্লিট JSON ইভেন্ট পেলোড (payload) থাকা ফাইলের পাথ।

এক্সপ্যান্ডেড পাথ দেখতে /home/runner/work/_temp/_github_workflow/event.json এর মত এবং এর ডেটা এর ওয়েবহুক ইভেন্ট (webhook event)-এর সাথে মিলে। ওয়েবহুক ইভেন্ট ডেটার ডকুমেন্টেশন পাওয়া যাবে গিটহাব REST API Event Types and Payloads-এ। ওয়ার্কফ্লো এনভায়রনমেন্টে JSON ডেটা উপলব্ধ করাতে, আপনি jq এর মত একটি টুল ব্যবহার করতে পারেন ইভেন্ট ডেটা পার্স (parse) করে এবং এনভায়রনমেন্ট ভেরিয়েবলে রাখতে।

নিচে, আমি একটি ইস্যু কমেন্ট ইভেন্ট (issue comment event) থেকে কমেন্ট আইডি (comment ID) গ্র্যাব (grab) করছি:

ID="$(jq '.comment.id' $GITHUB_EVENT_PATH)" 

অধিকাংশ ইভেন্ট ডেটা github.event কনটেক্সট ভেরিয়েবল (context variable) দিয়েও উপলব্ধ.JSON পার্স ছাড়া। ফিল্ডগুলো ডট নোটেশন (dot notation) দিয়ে অ্যাক্সেস করা হয়, নিচের উদাহরণে আমি একই কমেন্ট আইডি গ্র্যাব করছি:

ID=${{ github.event.comment.id }} 

আমার গেস্টবুকের জন্য, আমি এন্ট্রিগুলো ইউজারের হ্যান্ডেল (handle), এবং ডেট ও টাইম সহ ডিসপ্লে করতে চাই। আমি এই ইভেন্ট ডেটা ক্যাপচার (capture) করতে পারি এইভাবে:

AUTHOR=${{ github.event.comment.user.login }} DATE=${{ github.event.comment.created_at }} 

শেল ভেরিয়েবলস (Shell variables) ডেটা অ্যাক্সেস করার জন্য হ্যান্ডি (handy), কিন্তু সেগুলো এফিমারল (ephemeral)। ওয়ার্কফ্লো এনভায়রনমেন্ট প্রতিবার রান হলে নতুন তৈরি হয়, এবং এমনকি এক স্টেপে সেট করা শেল ভেরিয়েবলস অন্য স্টেপে পার্সিস্ট (persist) করে না। ক্যাপচার করা ডেটা পার্সিস্ট করার দুটি উপায় আছে: আর্টিফ্যাক্টস (artifacts) ব্যবহার করা, অথবা রিপোজিটরিতে কমিট (commit) করা।

ইভেন্ট ডেটা প্রিজার্ভ করা: আর্টিফ্যাক্টস (artifacts) ব্যবহার করে

আর্টিফ্যাক্টস ব্যবহার করে, আপনি ওয়ার্কফ্লো জবস (workflow jobs) এর মধ্যে ডেটা পার্সিস্ট করতে পারেন রিপোজিটরিতে কমিট ছাড়া। এটি হ্যান্ডি (handy) যখন, উদাহরণস্বরূপ, আপনি ডেটা ট্রান্সফর্ম (transform) বা ইনকর্পোরেট (incorporate) করতে চান যেকোনো постоян জায়গায় রাখার আগে। ওয়ার্কফ্লো জবসের মধ্যে ডেটা পার্সিস্ট করা প্রয়োজন কারণ:

একটি ওয়ার্কফ্লোর প্রতিটি জব একটি ফ্রেশ ইনস্ট্যান্সে (fresh instance) রান হয় ভার্চুয়াল এনভায়রনমেন্টের। জবটি কম্প্লিট হলে, রানার (runner) টার্মিনেট (terminate) হয় এবং ভার্চুয়াল এনভায়রনমেন্টের ইনস্ট্যান্সটি ডিলিট করে। (Persisting workflow data using artifacts)

আর্টিফ্যাক্টস ব্যবহার করার জন্য দুটি অ্যাকশন সাহায্য করে: upload-artifact এবং download-artifact। আপনি এই অ্যাকশনগুলো ব্যবহার করতে পারেন ফাইলগুলো একই ওয়ার্কফ্লোর অন্য জবসে উপলব্ধ করাতে। একটি ফুল উদাহরণের জন্য, "passing data between jobs in a workflow" দেখুন।

upload-artifact অ্যাকশনের action.yml কীওয়ার্ডগুলো এক্সপ্লেইন করে। আপলোড করা ফাইলগুলো .zip ফরম্যাটে সংরক্ষিত হয়। একই ওয়ার্কফ্লো রানের অন্য একটি জব download-artifact অ্যাকশন ব্যবহার করে ডেটা অন্য একটি স্টেপে ব্যবহার করতে পারে।

আপনি রিপোজিটরির Actions ট্যাবের অধীনে ওয়ার্কফ্লো রান পেজে ম্যানুয়ালি আর্কাইভটি ডাউনলোড করতে পারেন।

জবসের মধ্যে ওয়ার্কফ্লো ডেটা পার্সিস্ট করা রিপোজিটরি ফাইলগুলোর সাথে কোনো পরিবর্তন আননা, কারণ আর্টিফ্যাক্টস (artifacts) শুধু ওয়ার্কফ্লো এনভায়রনমেন্টে বাস করে।

ব্যক্তিগতভাবে, শেল এনভায়রনমেন্টে কাজ করতে কমফরটেবল থাকার কারণে, আমি আর্টিফ্যাক্টসের জন্য একটি সীমিত ইউজ কেস (use case) দেখি, যদিও আমি সেটি মেনশন (mention) না করলে রিমিস (remiss) হতাম। জবসের মধ্যে ডেটা পাস করার পাশাপাশি, সেগুলো যেমন টেস্ট আউটপুট ডেটার .zip ফরম্যাট আর্কাইভ তৈরি করার জন্য উপযোগী হতে পারে। আমার গেস্টবুক উদাহরণের কেসে, আমি শুধু এক জবেই সকল প্রয়োজনীয় স্টেপ রান করলাম, যেকোনো ডেটা জবসের মধ্যে পাস করার প্রয়োজন নেই।

ইভেন্ট ডেটা প্রিজার্ভ করা: ওয়ার্কফ্লো ফাইলস রিপোজিটরিতে পুশ (push) করে

ওয়ার্কফ্লোতে ক্যাপচার করা ডেটা রিপোজিটরিতে নিজে প্রিজার্ভ করতে হলে, এটি গিট রিপোজিটরিতে অ্যাড (add) এবং পুশ (push) করা প্রয়োজন। আপনি ওয়ার্কফ্লোতে শেল কমান্ড ব্যবহার করে নতুন ফাইল তৈরি করে ডেটা দিয়ে, বা বিদ্যমান ফাইলগুলোতে ডেটা অ্যাপেন্ড (append) করে এটি করতে পারেন।

ওয়ার্কফ্লোতে ফাইল তৈরি করা

ওয়ার্কফ্লোতে রিপোজিটরি ফাইলস দিয়ে কাজ করতে, প্রথমে checkout অ্যাকশন ব্যবহার করে একটি কপি আনুন কাজ করার জন্য:

- uses: actions/checkout@master with: fetch-depth: 1 

আমার গেস্টবুকে কমেন্ট যোগ করতে, আমি শেল ভেরিয়েবলসে ক্যাপচার করা ইভেন্ট ডেটা প্রপার ফাইলসে রূপান্তর করি, শেল প্যারামিটার এক্সপ্যানশনে সাবস্টিটিউশন (substitution) ব্যবহার করে ইউজার ইনপুট স্যানিটাইজ (sanitize) করতে এবং নিউলাইনকে প্যারাগ্রাফে ট্রান্সলেট করতে। আমি আগে লিখেছিলাম কেন ইউজার ইনপুট সতর্কতার সাথে বर्तাব করা উচিত।

- name: Turn comment into file run: | ID=${{ github.event.comment.id }} AUTHOR=${{ github.event.comment.user.login }} DATE=${{ github.event.comment.created_at }} COMMENT=$(echo "${{ github.event.comment.body }}") NO_TAGS=${COMMENT//[<>]/\`} FOLDER=comments printf '%b\n' "

${AUTHOR} says:

${NO_TAGS//$'\n'/<\/p>

}

${DATE}

\r\n" > ${FOLDER}/${ID}.html

printf ব্যবহার করে এবং এর আউটপুট > দিয়ে একটি নতুন ফাইলে ডাইরেক্ট করে, ইভেন্ট ডেটা একটি HTML ফাইলে রূপান্তরিত হয়, কমেন্ট আইডি নম্বর দিয়ে নামকরণ করা, যাতে ক্যাপচার করা ইভেন্ট ডেটা থাকে। ফরম্যাট করা হলে, এটি এমন দেখাবে:

victoriadrake says:

This is a comment!

2019-11-04T00:28:36Z

কমেন্টস দিয়ে কাজ করার সময়, কমেন্ট আইডি ব্যবহার করে ফাইল নামকরণের একটি ইফেক্ট হচ্ছে একই আইডি دار একটি নতুন ফাইল পূর্বের ফাইলটি ওভাররাইট (overwrite) করবে। এটি গেস্টবুকের জন্য হ্যান্ডি (handy), কারণ এটি যেকোনো কমেন্ট এডিট (edit) করার সুযোগ দেয় ওরিজিনাল কমেন্ট ফাইল রিপ্লেস করে।

আপনি যদি হিউগো (Hugo) এর মত একটি স্ট্যাটিক সাইট জেনারেটর (static site generator) ব্যবহার করেন, তবে আপনি একটি মার্কডাউন ফরম্যাট ফাইল বানাতে পারেন, সেটি আপনার content/ ফোল্ডারে রাখতে পারেন, এবং রেগুলার সাইট বিল্ড (site build) বাকি কাজটি হ্যান্ডেল করবে।

আমার সিম্পলিস্টিক (simplistic) গেস্টবুকের কেসে, আমার একটি এক্সট্রা স্টেপ আছে ইন্ডিভিজুয়াল কমেন্ট ফাইলগুলো এক পেজে কনসলিডেট (consolidate) করার জন্য। প্রতিবার রান হলে, এটি বিদ্যমান index.html ওভাররাইট করে header.html পোर्शन দিয়ে (>), তারপর খুঁজে বের করে এবং অ্যাপেন্ড (>>) করে সকল কমেন্ট ফাইল কন্টেন্ট ডিসেন্ডিং অর্ডারে (descending order), এবং শেষে footer.html পোर्शन অ্যাপেন্ড করে পেজটি শেষ করতে।

- name: Assemble page run: | cat header.html > index.html find comments/ -name "*.html" | sort -r | xargs -I % cat % >> index.html cat footer.html >> index.html 

রিপোজিটরিতে পরিবর্তনগুলো কমিট করা

যেহেতু checkout অ্যাকশন পুরোপুরি ক্লোনিং (cloning) রিপোজিটরির মত নয়, লিখার সময়, কিছু ইস্যু এখনও আছে যেগুলো ওয়ার্কআরাউন্ড (work around) করতে হবে। কিছু এক্সট্রা স্টেপ প্রয়োজন pull, checkout, এবং সফলভাবে push করার জন্য master ব্রাঞ্চে, কিন্তু এটি শেলে খুব ট্রিভিয়ালি (trivially) করা যায়।

নিচে সেই স্টেপটি দেওয়া হলো যা ওয়ার্কফ্লোতে তৈরি পরিবর্তনগুলো অ্যাড, কমিট, এবং রিপোজিটরির master ব্রাঞ্চে পুশ করে।

- name: Push changes to repo run: | REMOTE=https://${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} git config user.email "${{ github.actor }}@users.noreply.github.com" git config user.name "${{ github.actor }}" git pull ${REMOTE} git checkout master git add . git status git commit -am "Add new comment" git push ${REMOTE} master 

রিমোট (remote), আসলে আমাদের রিপোজিটরি, github.repository কনটেক্সট ভেরিয়েবল ব্যবহার করে স্পেসিফাইড (specified)। আমাদের ওয়ার্কফ্লোর master-এ পুশ করার অনুমতি দিতে, আমরা secrets.GITHUB_TOKEN ভেরিয়েবল ব্যবহার করি।

যেহেতু ওয়ার্কফ্লো এনভায়রনমেন্ট শyni (shiny) এবং নতুন (newborn), আমাদের গিট (Git) কনফিগার করতে হবে। উপরের উদাহরণে, আমি github.actor কনটেক্সট ভেরিয়েবল ব্যবহার করেছি ওয়ার্কফ্লো শুরু করে একাউন্টের ইউজারনেম ইনপুট করার জন্য। ইমেলও একইভাবে কনফিগার করা হয় ডিফল্ট noreply গিটহাব ইমেল অ্যাড্রেস দিয়ে।

ইভেন্ট ডেটা ডিসপ্লে করা

Nov 6, 2019 correction: গিটহাব অ্যাকশনস (GitHub Actions) একটি পারসোনাল অ্যাক্সেস টোকেন (Personal Access Token) চায় পেজস (Pages) সাইট বিল্ড ট্রিগার (trigger) করার জন্য।

আপনি যদি গিটহাব পেজেস (GitHub Pages) ডিফল্ট secrets.GITHUB_TOKEN ভেরিয়েবল এবং সাইট জেনারেটর ছাড়া ব্যবহার করেন, তবে ওয়ার্কফ্লোতে রিপোজিটরিতে পরিবর্তন পুশ করলে শুধু রিপোজিটরি ফাইলগুলো আপডেট হবে। গিটহাব পেজেস বিল্ড ফেইল (fail) করবে একটি এরর দিয়ে, "Your site is having problems building: Page build failed."

অ্যাকশনসকে (Actions) পেজস সাইট বিল্ড ট্রিগার করতে সক্ষম করতে, আপনাকে একটি পারসোনাল অ্যাক্সেস টোকেন (Personal Access Token) তৈরি করতে হবে। এই টোকেনটি রিপোজিটরি সেটিংসে একটি সিক্রেট (secret) হিসেবে সংরক্ষণ করা যাবে এবং ওয়ার্কফ্লোতে ডিফল্ট secrets.GITHUB_TOKEN ভেরিয়েবলের বদলে পাস করা যাবে। আমি অ্যাকশনস এনভায়রনমেন্ট এবং ভেরিয়েবলস সম্পর্কে এই পোস্টে আরো লিখেছি।

পারসোনাল অ্যাক্সেস টোকেনের ব্যবহার দিয়ে, অ্যাকশনস ওয়ার্কফ্লোতে শুরু করা একটি পুশ পেজস সাইটকেও আপডেট করবে। আপনি নিজেই দেখতে পারেন আমার গেস্টবুকে একটি কমেন্ট লিখে! কমেন্ট ক্রিয়েশন ইভেন্ট (comment creation event) ওয়ার্কফ্লো ট্রিগার করে, যা প্রায় ৩০ সেকেন্ড থেকে এক মিনিট নেয় রান হয়ে গেস্টবুক পেজ আপডেট করতে।

যেখানে সাইট বিল্ড প্রয়োজন পরিবর্তন পাবলিশ করার জন্য, যেন হিউগো (Hugo) ব্যবহার করার সময়, একটি অ্যাকশন (Action) সেটিও করতে পারে। যাইহোক, অনইন্টেনডন্ট লুপস (unintended loops) সৃষ্টি এড়াতে, একটি অ্যাকশন ওয়ার্কফ্লো অন্য একটি ট্রিগার করবে না। পরিবর্তে, সাইট বিল্ড করার প্রক্রিয়া একটি মেকফাইল (Makefile) দিয়ে হ্যান্ডেল করা অত্যন্ত সুবিধাজনক, যা যেকোনো ওয়ার্কফ্লো চালাতে পারে। সিম্পলি আপনার ওয়ার্কফ্লো জবের ফাইনাল স্টেপ হিসেবে মেকফাইল রান করা যোগ করুন, রিপোজিটরি টোকেন যেখানে প্রয়োজন:

- name: Run Makefile env: TOKEN: ${{ secrets.GITHUB_TOKEN }} run: make all 

এটি নিশ্চিত করে যে আপনার ওয়ার্কফ্লোর ফাইনাল স্টেপ আপডেটেড সাইট বিল্ড ও ডিপ্লয় (deploy) করে।

নো মোর ইভেন্ট ডেটা হরাইজন (No more event data horizon)

গিটহাব অ্যাকশনস (GitHub Actions) একটি সাফ উপায় দিয়েছে ইভেন্ট ডেটা ক্যাপচার (capture) এবং ইউটিলাইজ (utilize) করার জন্য যাতে সেটি শুধু গিটহাবের ভিতরে নয় উপলব্ধ। সম্ভাবনাগুলো শুধু আপনার ইম্যাজিনেশন (imagination) দিয়ে সীমাবদ্ধ! এখানে কিছু আইডিয়া যা এটি আমাদের তৈরি করতে দেয়:

  1. একটি পাবলিক-ফেসিং ইস্যু বোর্ড (public-facing issues board), যেখানে গিটহাব একাউন্ট ছাড়া কাস্টমাররা প্রজেক্ট ইস্যুগুলো দেখতে এবং ফিডব্যাক (feedback) দিতে পারবে।
  2. যেকোনো রিপোজিটরির নতুন ইস্যু, কমেন্ট, বা PR-র একটি অটোমেটিক্যালি-আপডেটিং RSS ফিড (automatically-updating RSS feed)।
  3. স্ট্যাটিক সাইটের জন্য একটি কমেন্ট সিস্টেম (comments system), গিটহাব ইস্যু কমেন্টকে ইনপুট মেথড (input method) হিসেবে ব্যবহার করে।
  4. একটি চমৎকার ৯০-এর দশকের গেস্টবুক পেজ।

আমি কি মেনশন করেছিলাম আমি একটি ৯০-এর দশকের গেস্টবুক পেজ বানালাম? আমার ইনার-জিওসিটিজ-নার্ড (inner-Geocities-nerd) একটু একসাইটেড (excited)।

  1. স্ল্যাক থেকে মাইক্রোসফট টিমসে সুগম মাইগ্রেশন: সহজে আপনার ডেটা ট্রান্সফার করুন

  2. গিটহাব মার্কেটপ্লেসে আপনার অ্যাপ পাবলিশ করুন: লিস্টিং ও ভিজিবিলিটির ধাপে ধাপে গাইড

  3. গুগল ড্রাইভ ব্যাকআপ ও এনক্রিপশন দিয়ে আপনার হোয়াটসঅ্যাপ ডেটা সুরক্ষিত করুন

  4. উইন্ডোজ ১০-এ File History দিয়ে ফাইল সेफগার্ড ও রিস্টোর: সম্পূর্ণ গাইড