Lane — এটি কী, Fastlane-এ তৈরি এবং ব্যবহার

লেখক: IT Sectr প্রকাশিত: 2026-04-14 পড়ার সময়: 10 মিনিট

Lane হল Fastlane-এ একটি নামকৃত অটোমেশন স্ক্রিপ্ট যা একটি মোবাইল অ্যাপ্লিকেশন বিল্ড, টেস্ট বা ডেলিভারির জন্য ক্রিয়াগুলির (actions) একটি ক্রম একত্রিত করে। প্রতিটি lane Fastfile-এ Ruby ভাষায় সংজ্ঞায়িত করা হয় এবং টার্মিনাল বা CI/CD সিস্টেম থেকে একটি কমান্ড দিয়ে চালানো যেতে পারে। Fastlane Docs, 2025 অনুসারে, 85% Fastfiles-এ CI/CD-এর বিভিন্ন ধাপের জন্য তিনটির বেশি lanes থাকে। Lane প্যারামিটার গ্রহণ করতে পারে, অন্যান্য lanes কল করতে পারে এবং এক্সিকিউশন ত্রুটিগুলি পরিচালনা করতে পারে।

মূল বিষয়

  • Lane — Fastfile-এ Ruby ভাষায় একটি নামকৃত অটোমেশন স্ক্রিপ্ট
  • প্যারামিটার — fastlane lane_name key:value চালানোর সময় options হ্যাশের মাধ্যমে মান পাস করা
  • before_all/after_all — প্রতিটি lane-এর আগে এবং পরে কোড কার্যকর করার ব্লক
  • Private lane — শুধুমাত্র অন্যান্য lanes থেকে কল করার জন্য উপলব্ধ স্ক্রিপ্ট
  • ত্রুটি পরিচালনা — ত্রুটি পরিচালনা এবং বিজ্ঞপ্তি পাঠানোর জন্য error ব্লক

Fastlane-এ Lane কী

Lane হল Fastlane-এর মৌলিক বিল্ডিং ব্লক যা একটি নামকৃত অটোমেশন স্ক্রিপ্ট সংজ্ঞায়িত করে। প্রতিটি lane ক্রিয়াগুলির একটি ক্রম বর্ণনা করে যা একটি নির্দিষ্ট লক্ষ্য অর্জনের জন্য কার্যকর করা হয়: একটি অ্যাপ্লিকেশন বিল্ড করা, টেস্ট চালানো, স্টোরে বিল্ড আপলোড করা বা পরিবেশ সেট আপ করা। Lane Fastfile-এ ঘোষণা করা হয় এবং প্রকল্প রুট থেকে fastlane [lane_name] কমান্ড দিয়ে চালানো হয়।

Lane ধারণাটি Ruby DSL থেকে নেওয়া এবং স্ক্রিপ্টের পঠনযোগ্যতা নিশ্চিত করে। ডেভেলপার সম্পূর্ণ CI/CD প্রক্রিয়াটিকে স্পষ্ট নাম এবং প্যারামিটার সহ ক্রিয়া কলের একটি ক্রম হিসাবে দেখেন। Lane সরল (একটি কমান্ড) বা জটিল (শাখা, লুপ, অন্যান্য lanes কল করা) হতে পারে।

এক্সিকিউশনের পরে, প্রতিটি lane একটি ফলাফল ফেরত দেয় — একটি অবজেক্ট যাতে এক্সিকিউশন স্থিতি এবং ক্রিয়াগুলির ডেটা থাকে। ফলাফল অন্যান্য lanes-এ ব্যবহার করা যেতে পারে বা সিদ্ধান্ত নেওয়ার জন্য CI/CD সিস্টেমে পাঠানো যেতে পারে। যদি lane-এর কোনো ক্রিয়া ব্যর্থ হয়, lane-এর এক্সিকিউশন বন্ধ হয়ে যায় এবং error ব্লক কল করা হয়।

Lane সিনট্যাক্স: ঘোষণা এবং চালানো

Lane ঘোষণা সিনট্যাক্স একটি সরল Ruby DSL প্যাটার্ন অনুসরণ করে: lane কীওয়ার্ড, Ruby প্রতীক (symbol) হিসাবে স্ক্রিপ্টের নাম, এবং do ... end ব্লক স্ক্রিপ্টের মূল অংশ সহ। Lane-এর নাম প্ল্যাটফর্মের মধ্যে অনন্য হতে হবে এবং অক্ষর, সংখ্যা এবং আন্ডারস্কোর নিয়ে গঠিত হতে পারে।

একটি lane কমান্ড লাইনের মাধ্যমে চালানো হয়: fastlane build (:build নামের lane-এর জন্য) বা bundle exec fastlane build (যদি Fastlane Bundler-এর মাধ্যমে ইনস্টল করা হয়)। প্ল্যাটফর্ম-নির্দিষ্ট lanes-এর জন্য, fastlane ios build বা fastlane android build ব্যবহার করুন।

ruby
# একটি সরল lane ঘোষণা
lane :test do
  scan(scheme: 'App', devices: ['iPhone 15'])
end

lane :build_and_deploy do
  cocoapods
  test
  gym(scheme: 'App', export_method: 'app-store')
  pilot(skip_waiting_for_build_processing: true)
end

# চালান: fastlane build_and_deploy

একটি lane-এ প্যারামিটার বা পরিবেশ চলকের উপর ভিত্তি করে শর্তযুক্ত যুক্তি থাকতে পারে। নির্দিষ্ট শর্তে ধাপগুলি এড়াতে if/unless ব্যবহার করুন। অ্যারে প্রক্রিয়াকরণের জন্য লুপ (each) উপলব্ধ, যা একটি একক lane-এ একাধিক টার্গেট বা অ্যাপ স্কিম বিল্ড করার জন্য সুবিধাজনক।

Lane থেকে মান ফেরত দেওয়া

একটি lane একটি মান ফেরত দিতে পারে যা কলিং কোডের জন্য উপলব্ধ হবে। মান ফেরত দিতে স্ট্যান্ডার্ড Ruby return বা lane ব্লকের শেষ এক্সপ্রেশন ব্যবহার করুন। ফেরত দেওয়া মান একটি স্ট্রিং, সংখ্যা, হ্যাশ বা কোনো ক্রিয়ার ফলাফল হতে পারে। এটি সিদ্ধান্ত নেওয়ার জন্য একটি lane-এর ফলাফল অন্য lane-এ ব্যবহার করার অনুমতি দেয়।

উদাহরণস্বরূপ, একটি :get_version lane Info.plist থেকে অ্যাপ্লিকেশনের বর্তমান সংস্করণ ফেরত দিতে পারে, এবং :deploy lane এটি একটি Slack বার্তা তৈরি করতে ব্যবহার করতে পারে। ফেরত দেওয়া মান বিশেষ করে private lanes-এ কার্যকর যেখানে কলিং lane-এ আরও প্রক্রিয়াকরণের জন্য ফলাফলের প্রয়োজন হয়।

Lanes-এর প্যারামিটার: পাস এবং প্রক্রিয়াকরণ

Lane প্যারামিটার স্ক্রিপ্টগুলিকে নমনীয় এবং পুনর্ব্যবহারযোগ্য করে তোলে। Lane options হ্যাশের মাধ্যমে প্যারামিটার গ্রহণ করে, যা কমান্ড লাইন থেকে চালানোর সময় পাস করা হয়: fastlane deploy scheme:AppStore version:2.1.0। Lane-এর ভিতরে, প্যারামিটার options[:scheme] এবং options[:version] হিসাবে উপলব্ধ।

বাধ্যতামূলক প্যারামিটার-এর জন্য, lane-এর শুরুতে মান পরীক্ষা করুন এবং একটি স্পষ্ট বার্তা সহ UI.user_error! কল করুন। ঐচ্ছিক প্যারামিটারের জন্য, || অপারেটরের মাধ্যমে ডিফল্ট মান সেট করুন। Fastlane প্রকার, ডিফল্ট মান এবং বিবরণ সহ options পদ্ধতির মাধ্যমে টাইপ করা প্যারামিটারও সমর্থন করে।

ruby
# প্যারামিটার পরিচালনা সহ Lane
lane :deploy do |options|
  scheme = options[:scheme]
  version = options[:version] || '1.0.0'
  beta = options[:beta] || false

  UI.user_error!("scheme নির্দিষ্ট করা হয়নি") unless scheme

  match(type: beta ? 'adhoc' : 'appstore')
  gym(scheme: scheme, export_method: beta ? 'ad-hoc' : 'app-store')

  if beta
    pilot(distribute_external: true)
  else
    deliver(submit_for_review: true)
  end
end

# চালান: fastlane deploy scheme:MyApp beta:true version:2.1.0

Lane-এর ভিতরে পরিবেশ চলক নিয়ে কাজ করতে, ENV['VARIABLE_NAME'] ব্যবহার করুন। Fastlane স্বয়ংক্রিয়ভাবে fastlane ডিরেক্টরি থেকে .env ফাইল লোড করে। এটি Fastfile-এ সংরক্ষণ না করে CI/CD পরিবেশে সংবেদনশীল ডেটা — API কী, পাসওয়ার্ড এবং টোকেন — পাস করার মানক উপায়।

প্যারামিটার বৈধকরণ

নির্ভরযোগ্য lane অপারেশনের জন্য, ইনপুটে প্যারামিটার বৈধকরণ প্রয়োজনীয়। যদি বাধ্যতামূলক প্যারামিটার অনুপস্থিত থাকে বা এর প্রকার ভুল হয়, তাহলে সমস্যা বিবরণ সহ UI.user_error! ব্যবহার করুন। Fastlane options পদ্ধতি প্রদান করে, যা প্রতিটি প্যারামিটারের জন্য প্রকার (String, Boolean, Integer, Array), ডিফল্ট মান এবং বিবরণ নির্দিষ্ট করার অনুমতি দেয় — lane শুরু হলে বৈধকরণ স্বয়ংক্রিয়ভাবে সম্পাদিত হয়।

অতিরিক্তভাবে, আপনি স্ট্রিং প্যারামিটারের জন্য verify ব্লকের মাধ্যমে পরীক্ষা ব্যবহার করতে পারেন: verify do |value| value.length > 0 end। যদি ফরম্যাট ভুল হয়, Fastlane প্রত্যাশিত ফরম্যাট এবং পাস করা মান নির্দেশ করে একটি স্পষ্ট বার্তা আউটপুট করে, যা CI/CD পরিবেশে ডিবাগিং সহজ করে।

Lanes একত্রিত করা: before_all, after_all এবং ত্রুটি পরিচালনা

Fastlane প্রতিটি lane-এর আগে এবং পরে কোড কার্যকর করার জন্য জীবনচক্র হুক প্রদান করে। before_all ব্লক একটি নির্দিষ্ট প্ল্যাটফর্মে বা বিশ্বব্যাপী প্রতিটি lane-এর আগে কার্যকর হয়। after_all ব্লক একটি lane সফলভাবে সম্পূর্ণ হওয়ার পরে কার্যকর হয়। error ব্লক lane-এর ভিতরে কোনো ত্রুটিতে কার্যকর হয়।

হুকগুলি পুনরাবৃত্ত যুক্তিকে কেন্দ্রীভূত করার অনুমতি দেয়: before_all-এ নির্ভরতা সেটআপ, after_all-এ বিজ্ঞপ্তি পাঠানো, অস্থায়ী ফাইল পরিষ্কার করা এবং error ব্লকে ত্রুটি বিজ্ঞপ্তি। এটি কোড পুনরাবৃত্তি হ্রাস করে এবং lanes পরিষ্কার রাখে।

ruby
# Lanes-এর জীবনচক্র হুক
default_platform(:ios)

before_all do
  cocoapods(try_repo_update_on_error: true)
  ensure_git_status_clean
end

after_all do |lane|
  slack(message: "Lane #{lane} সফলভাবে সম্পন্ন হয়েছে")
end

error do |lane, exception|
  slack(
    message: "Lane #{lane} ত্রুটির সাথে ব্যর্থ হয়েছে: #{exception}",
    success: false
  )
end

lane :deploy do
  match(type: 'appstore')
  gym(export_method: 'app-store')
  deliver
end

Error ব্লক দুটি আর্গুমেন্ট গ্রহণ করে: lane-এর নাম (symbol) এবং ব্যতিক্রম অবজেক্ট। ব্লকের ভিতরে, আপনি একটি Slack বিজ্ঞপ্তি পাঠাতে পারেন, একটি ফাইলে লগ লিখতে পারেন বা একটি বিকল্প পুনরুদ্ধার স্ক্রিপ্ট চালাতে পারেন। যদি error ব্লক সফলভাবে সম্পূর্ণ হয়, Fastlane CI/CD স্তরে বিল্ডটি ব্যর্থ বলে বিবেচনা করে না।

Private lanes এবং পুনর্ব্যবহার

Private lane হল একটি lane যা lane-এর পরিবর্তে private_lake-এর মাধ্যমে ঘোষণা করা হয়, যা উপলব্ধ কমান্ডের তালিকায় প্রদর্শিত হয় না এবং সরাসরি টার্মিনাল থেকে চালানো যায় না। Private lanes একাধিক পাবলিক lanes থেকে কল করা পুনরাবৃত্ত পদক্ষেপগুলিকে এনক্যাপসুলেট করার জন্য ডিজাইন করা হয়েছে।

Private lanes বিশেষ করে ক্রিয়াগুলির জটিল ক্রম-এর জন্য কার্যকর যা কঠোরভাবে সংজ্ঞায়িত ক্রমে কার্যকর করা আবশ্যক। উদাহরণস্বরূপ, একটি private lane :setup_signing বিভিন্ন প্যারামিটার সহ lanes :build_dev, :build_staging এবং :build_production থেকে কল করা যেতে পারে, কিন্তু নিজে থেকে একটি পৃথক কমান্ড হিসাবে এর কোনো অর্থ নেই।

ruby
# পুনর্ব্যবহারের জন্য Private lanes
private_lane :setup_environment do |options|
  cocoapods(try_repo_update_on_error: true)
  match(type: options[:type], readonly: true)
  increment_build_number
end

lane :dev_build do
  setup_environment(type: 'development')
  gym(export_method: 'development')
end

lane :appstore_build do
  setup_environment(type: 'appstore')
  gym(export_method: 'app-store')
  deliver
end

Private lanes অন্যান্য private lanes কল করতে পারে, একটি অ্যাবস্ট্রাকশন শ্রেণিবিন্যাস গঠন করে। Fastfile-এর পঠনযোগ্যতা বজায় রাখতে নেস্টিং গভীরতা 2–3 স্তরে সীমাবদ্ধ করার পরামর্শ দেওয়া হয়। প্রতিটি private lane-কে তার উদ্দেশ্য এবং প্রত্যাশিত প্যারামিটার বর্ণনাকারী মন্তব্য সহ ডকুমেন্ট করুন।

iOS এবং Android-এর জন্য lanes-এর উদাহরণ

আসুন iOS এবং Android প্রকল্পের জন্য lanes-এর ব্যবহারিক উদাহরণ দেখি। iOS lanes সাধারণত পরীক্ষার জন্য scan, সার্টিফিকেটের জন্য match, বিল্ডের জন্য gym এবং বিতরণের জন্য pilot বা deliver ব্যবহার করে। Android lanes বিল্ডের জন্য gradle, প্রকাশনার জন্য supply এবং ক্লাউড পরীক্ষার জন্য firebase_test_lab ব্যবহার করে।

ruby
// সম্পূর্ণ CI/CD iOS অ্যাপের জন্য Lane
lane :ci_full_ios do
  scan(scheme: 'App', code_coverage: true)
  gym(scheme: 'App', export_method: 'app-store')
  pilot(distribute_external: true)
  slack(message: 'iOS CI/CD সফলভাবে সম্পূর্ণ হয়েছে')
end

/* সম্পূর্ণ CI/CD Android অ্যাপের জন্য Lane */
lane :ci_full_android do
  gradle(task: 'testReleaseUnitTest')
  gradle(task: 'bundleRelease')
  supply(track: 'internal')
end

iOS এবং Android-এর জন্য lanes একত্রিত করে, আপনি একটি ক্রস-প্ল্যাটফর্ম অ্যাপ্লিকেশনের জন্য একটি একীভূত CI/CD প্রক্রিয়া তৈরি করতে পারেন। প্ল্যাটফর্ম-নির্দিষ্ট lanes গ্রুপ করতে প্ল্যাটফর্ম ব্লক platform :ios এবং platform :android ব্যবহার করুন এবং সেগুলিকে একটি সাধারণ অর্কেস্ট্রেটর lane থেকে কল করুন যা এক্সিকিউশন ক্রম পরিচালনা করে।

Lanes লেখার সেরা অনুশীলন

Lanes লেখার সময়, অনুশীলনের একটি সেট অনুসরণ করার পরামর্শ দেওয়া হয় যা স্ক্রিপ্টের পঠনযোগ্যতা, রক্ষণাবেক্ষণযোগ্যতা এবং নির্ভরযোগ্যতা নিশ্চিত করে। প্রথম নিয়ম হল প্রতিটি lane-এর একটি কাজ করা উচিত। যদি কোনো lane খুব বেশি করে, তবে এটিকে একাধিক lanes এবং private lanes-এ ভাগ করুন।

দ্বিতীয় নিয়ম হল lane-এর নামকরণ একটি ক্রিয়া বা ক্রিয়া বাক্যাংশ হওয়া উচিত: build, deploy, test, upload_screenshots। process বা do_all-এর মতো বিমূর্ত নাম এড়িয়ে চলুন। Lane-এর নামে শব্দ আলাদা করতে আন্ডারস্কোর ব্যবহার করুন।

তৃতীয় নিয়ম হল স্পষ্টভাবে ত্রুটিগুলি পরিচালনা করা। স্পষ্ট সমস্যা বার্তার জন্য UI.user_error! ব্যবহার করুন। Fastlane-এর ডিফল্ট ত্রুটি বার্তার উপর নির্ভর করবেন না — ডেভেলপারকে প্রসঙ্গ দিন: “GoogleService-Info.plist ফাইল পাওয়া যায়নি — এটি প্রকল্পে যোগ করুন” “ফাইল পাওয়া যায়নি”-এর পরিবর্তে।

অনুশীলনবিবরণউদাহরণ
একটি কাজLane একটি যৌক্তিক অপারেশন করেlane :run_tests, lane :build_ipa
প্যারামিটারসব সেটিংস options বা ENV-এর মাধ্যমেoptions[:scheme] || default
হুকসাধারণ কোডের জন্য before_all/after_allcocoapods in before_all
মন্তব্যজটিল বিভাগ ডকুমেন্ট করুন# bitcode সহ বিল্ড
ত্রুটিস্পষ্ট ত্রুটি বার্তাUI.user_error!(“...”)

চতুর্থ নিয়ম হল CI/CD-তে চালানোর আগে স্থানীয়ভাবে lanes পরীক্ষা করা। Fastlane --dry-run ফ্ল্যাগের মাধ্যমে ড্রাই-রান মোড সমর্থন করে, যা প্রকৃতপক্ষে চালানো ছাড়াই দেখায় কোন ক্রিয়াগুলি কার্যকর হবে। ইন্টিগ্রেশনের আগে পৃথক lanes-এর বিচ্ছিন্ন পরীক্ষার জন্য fastlane run_test ব্যবহার করুন।

Lanes-এর ডকুমেন্টেশন

প্রতিটি lane-এর ডকুমেন্টেশন টিম ডেভেলপমেন্টের জন্য একটি গুরুত্বপূর্ণ অনুশীলন। Fastlane lane ঘোষণার আগে রাখা desc ব্লক থেকে স্বয়ংক্রিয় ডকুমেন্টেশন জেনারেশন সমর্থন করে। fastlane lanes এবং fastlane list চালানোর সময় desc টেক্সট প্রদর্শিত হয়, যা ডেভেলপারদের Fastfile-এর সোর্স কোড না পড়েই প্রতিটি স্ক্রিপ্টের উদ্দেশ্য বুঝতে সাহায্য করে।

প্যারামিটার ডকুমেন্ট করতে, প্রত্যাশিত মান বর্ণনাকারী Ruby মন্তব্য ব্যবহার করুন। Fastlane fastlane generate_docs কমান্ডের মাধ্যমে lanes এবং তাদের বিবরণের সম্পূর্ণ তালিকা সহ README.md জেনারেট করতে পারে, যা প্রকল্পের CI/CD প্রক্রিয়ায় নতুন টিম সদস্যদের অন্তর্ভুক্ত করার জন্য সুবিধাজনক।

সচরাচর জিজ্ঞাসা

Fastlane-এ Lane কী?

Lane হল Fastlane-এ একটি নামকৃত অটোমেশন স্ক্রিপ্ট, যা Ruby-তে Fastfile-এ ঘোষণা করা হয়। Lane একটি নির্দিষ্ট কাজ সম্পাদনের জন্য ক্রিয়াগুলির একটি ক্রম একত্রিত করে: একটি অ্যাপ্লিকেশন বিল্ড করা, টেস্ট চালানো বা ডিপ্লয় করা। এটি টার্মিনাল বা CI/CD সিস্টেম থেকে fastlane [lane_name] এর মাধ্যমে চালানো হয়।

Fastfile-এ Lane কীভাবে তৈরি করবেন?

Fastfile-এ lane :name do ... end কনস্ট্রাক্ট ব্যবহার করুন। ব্লকের ভিতরে, প্যারামিটার সহ ক্রিয়া কল যোগ করুন। Lane নাম দ্বারা অন্যান্য lanes কল করতে পারে। এটি চালানোর জন্য, প্রকল্প রুট থেকে টার্মিনালে fastlane name এক্সিকিউট করুন, যেখানে Fastfile সহ fastlane ডিরেক্টরি অবস্থিত।

Lane-এ প্যারামিটার কীভাবে পাস করবেন?

প্যারামিটার কমান্ড লাইন এর মাধ্যমে পাস করা হয়: fastlane build scheme:App version:2.0। Lane-এর ভিতরে, প্যারামিটার options[:scheme] এবং options[:version] এর মাধ্যমে উপলব্ধ। বাধ্যতামূলক প্যারামিটারের জন্য, lane-এর শুরুতে মান পরীক্ষা করুন; ঐচ্ছিক প্যারামিটারের জন্য, ডিফল্ট মান সেট করুন।

Fastlane-এ private lane কী?

Private lane হল একটি lane যা lane-এর পরিবর্তে private_lane দিয়ে ঘোষণা করা হয়। এটি সরাসরি কমান্ড লাইন থেকে চালানো যায় না এবং অন্যান্য lanes থেকে কল করা পুনরাবৃত্ত পদক্ষেপগুলি এনক্যাপসুলেট করতে কাজ করে। এটি কোড পুনরাবৃত্তি হ্রাস করে এবং Fastfile-এর রক্ষণাবেক্ষণ সহজ করে।

Lane-এ ত্রুটিগুলি কীভাবে পরিচালনা করবেন?

ব্যতিক্রম ধরতে বিশ্বব্যাপী বা একটি নির্দিষ্ট lane-এর ভিতরে error ব্লক ব্যবহার করুন। Fastlane ব্লকে lane-এর নাম এবং exception অবজেক্ট পাঠায়। ব্লকের ভিতরে, আপনি একটি বিজ্ঞপ্তি পাঠাতে পারেন, লগ লিখতে পারেন বা পরিষ্কার করতে পারেন। স্পষ্ট ত্রুটি বার্তা তৈরি করতে UI.user_error! ব্যবহার করুন।

সারাংশ

  • Lane — Fastlane-এ Ruby-তে একটি নামকৃত অটোমেশন স্ক্রিপ্ট, CI/CD কাজের জন্য ক্রিয়া একত্রিত করে
  • সিনট্যাক্স — lane :name do ... end options হ্যাশ এবং পরিবেশ চলকের মাধ্যমে প্যারামিটার সমর্থন সহ
  • হুক — কেন্দ্রীভূত lane জীবনচক্র ব্যবস্থাপনার জন্য before_all, after_all এবং error ব্লক
  • Private lane — সরাসরি এক্সিকিউশন ছাড়া পুনরাবৃত্ত যুক্তি এনক্যাপসুলেট করার জন্য প্রাইভেট স্ক্রিপ্ট
  • iOS lanes পরীক্ষা, বিল্ড এবং বিতরণের জন্য scan, gym, match, pilot ব্যবহার করে
  • Android lanes Gradle-এর মাধ্যমে বিল্ড এবং Google Play-তে প্রকাশনার জন্য gradle এবং supply ব্যবহার করে
  • সেরা অনুশীলন: একটি lane — একটি কাজ, স্পষ্ট প্যারামিটার, পরিষ্কার ত্রুটি, dry-run-এর মাধ্যমে পরীক্ষা

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন