మొబైల్ CICD అనుభవం: అనేక మొబైల్ అప్లికేషన్‌ల కోసం ఒక ఫాస్ట్‌లేన్ ప్రమాణం

మొబైల్ CICD అనుభవం: అనేక మొబైల్ అప్లికేషన్‌ల కోసం ఒక ఫాస్ట్‌లేన్ ప్రమాణం
నేను ఫాస్ట్‌లేన్‌ని ఉపయోగించి మొబైల్ యాప్‌ల కోసం నిరంతర ఏకీకరణ మరియు డెలివరీ గురించి మాట్లాడాలనుకుంటున్నాను. మేము అన్ని మొబైల్ అప్లికేషన్‌లలో CI/CDని ఎలా అమలు చేస్తాము, మేము అక్కడికి ఎలా వచ్చాము మరియు చివరికి ఏమి జరిగింది.

సాధనంలోని నెట్‌వర్క్‌లో ఇప్పటికే తగినంత మెటీరియల్ ఉంది, ఇది ప్రారంభంలో మనకు లేదు, కాబట్టి నేను ఉద్దేశపూర్వకంగా సాధనాన్ని వివరంగా వివరించను, కానీ మనం కలిగి ఉన్న వాటిని మాత్రమే సూచిస్తాను:

వ్యాసం రెండు భాగాలను కలిగి ఉంటుంది:

  • కంపెనీలో మొబైల్ CI/CD ఆవిర్భావానికి నేపథ్యం
  • N-అప్లికేషన్‌ల కోసం CI/CDని విడుదల చేయడానికి సాంకేతిక పరిష్కారం

మొదటి భాగం పాత రోజులకు మరింత వ్యామోహం, మరియు రెండవది మీకు మీరే దరఖాస్తు చేసుకోగల అనుభవం.

చారిత్రాత్మకంగా ఇలా జరిగింది

సంవత్సరం 2015

మేము ఇప్పుడే మొబైల్ అప్లికేషన్‌లను డెవలప్ చేయడం ప్రారంభించాము, ఆ తర్వాత నిరంతర ఏకీకరణ గురించి, DevOps గురించి మరియు ఇతర ఫ్యాషన్ విషయాల గురించి మాకు ఏమీ తెలియదు. ప్రతి అప్లికేషన్ అప్‌డేట్‌ను డెవలపర్ స్వయంగా తన మెషీన్ నుండి రూపొందించారు. మరియు Android కోసం ఇది చాలా సులభం అయితే - సమావేశమై, సంతకం చేయబడింది .apk మరియు దానిని Google డెవలపర్ కన్సోల్‌కి అప్‌లోడ్ చేసారు, ఆపై iOS కోసం Xcode ద్వారా పంపిణీ సాధనం మాకు గొప్ప సాయంత్రాలను అందించింది - ఆర్కైవ్‌ను డౌన్‌లోడ్ చేసే ప్రయత్నాలు తరచుగా లోపాలతో ముగుస్తాయి మరియు మేము మళ్లీ ప్రయత్నించవలసి ఉంటుంది. అత్యంత అధునాతన డెవలపర్ నెలకు చాలాసార్లు కోడ్ రాయలేదని, కానీ అప్లికేషన్‌ను విడుదల చేస్తుందని తేలింది.

సంవత్సరం 2016

మేము పెరిగాము, విడుదల కోసం ఒక రోజు మొత్తం డెవలపర్‌లను ఎలా విడిపించాలనే దాని గురించి మాకు ఇప్పటికే ఆలోచనలు ఉన్నాయి మరియు రెండవ అప్లికేషన్ కూడా కనిపించింది, ఇది మమ్మల్ని ఆటోమేషన్ వైపు మరింతగా నెట్టింది. అదే సంవత్సరం, మేము మొదటిసారిగా జెంకిన్స్‌ని ఇన్‌స్టాల్ చేసాము మరియు దాని డాక్యుమెంటేషన్‌లో ఫాస్ట్‌లేన్ చూపించే వాటికి సమానమైన స్కేరీ స్క్రిప్ట్‌ల సమూహాన్ని వ్రాసాము.

$ xcodebuild clean archive -archivePath build/MyApp 
    -scheme MyApp

$ xcodebuild -exportArchive 
                        -exportFormat ipa 
                        -archivePath "build/MyApp.xcarchive" 
                        -exportPath "build/MyApp.ipa" 
                        -exportProvisioningProfile "ProvisioningProfileName"

$ cd /Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/

$ ./altool —upload-app 
-f {abs path to your project}/build/{release scheme}.ipa  
-u "[email protected]" 
-p "PASS_APPLE_ID"

దురదృష్టవశాత్తూ, ఇప్పటి వరకు మా డెవలపర్‌లకు మాత్రమే ఈ స్క్రిప్ట్‌లు ఎలా పని చేస్తాయో మరియు ఈ అంతులేని కీల స్టాక్ ఎందుకు అవసరమో తెలుసు, మరియు మళ్లీ ఏదైనా విరిగిపోయినప్పుడు, లాగ్‌లను విశ్లేషించడానికి వారు “అద్భుతమైన సాయంత్రాలు” పొందారు.

సంవత్సరం 2017

ఫాస్ట్‌లేన్ అనే విషయం ఉందని ఈ సంవత్సరం మేము తెలుసుకున్నాము. ఇప్పుడు ఉన్నంత సమాచారం లేదు - ఒకదాన్ని ఎలా ప్రారంభించాలి, ఎలా ఉపయోగించాలి. మరియు ఆ సమయంలో సాధనం ఇప్పటికీ ముడిపడి ఉంది: స్థిరమైన లోపాలు మమ్మల్ని నిరాశపరిచాయి మరియు వారు వాగ్దానం చేసిన మాయా ఆటోమేషన్‌ను నమ్మడం కష్టం.

అయితే, ఫాస్ట్‌లేన్ కోర్‌లో చేర్చబడిన ప్రధాన యుటిలిటీలు gym и pilot, మేము దీన్ని ప్రారంభించగలిగాము.

మా స్క్రిప్ట్‌లు కొద్దిగా మెరుగుపడ్డాయి.

$ fastlane gym  —-workspace "Example.xcworkspace" 
                --scheme "AppName" 
                —-buildlog_path "/tmp" 
                -—clean

అవసరమైన అన్ని పారామితులు లేనందున అవి మెరుగుపరచబడ్డాయి xcodebuild, మీరు సూచించాలి - gym ఎక్కడ మరియు ఏది అబద్ధం అని స్వతంత్రంగా అర్థం చేసుకుంటుంది. మరియు మరింత ఫైన్-ట్యూనింగ్ కోసం, మీరు అదే కీలను పేర్కొనవచ్చు xcodebuild, కీల పేరు మాత్రమే స్పష్టంగా ఉంటుంది.

ఈసారి, జిమ్ మరియు అంతర్నిర్మిత xcpretty ఫార్మాట్‌కు ధన్యవాదాలు, బిల్డ్ లాగ్‌లు మరింత స్పష్టంగా ఉన్నాయి. ఇది విరిగిన సమావేశాలను పరిష్కరించడంలో సమయాన్ని ఆదా చేయడం ప్రారంభించింది మరియు కొన్నిసార్లు విడుదల బృందం వారి స్వంతదానిని గుర్తించగలదు.

దురదృష్టవశాత్తు, అసెంబ్లీ వేగం కొలతలు xcodebuild и gym మేము దీన్ని చేయలేదు, కానీ మేము డాక్యుమెంటేషన్‌ను విశ్వసిస్తాము - గరిష్టంగా 30% స్పీడప్.

అన్ని అప్లికేషన్‌ల కోసం ఒకే ప్రక్రియ

సంవత్సరం 2018 మరియు ప్రస్తుతం

2018 నాటికి, అప్లికేషన్‌లను రూపొందించే మరియు విడుదల చేసే ప్రక్రియ పూర్తిగా జెంకిన్స్‌కు తరలించబడింది, డెవలపర్‌లు వారి మెషీన్‌ల నుండి విడుదల చేయడం ఆపివేసారు మరియు విడుదల బృందానికి మాత్రమే విడుదల చేసే హక్కు ఉంది.

మేము ఇప్పటికే పరీక్షలు మరియు స్టాటిక్ విశ్లేషణల ప్రారంభాన్ని మెరుగుపరచాలనుకుంటున్నాము మరియు మా స్క్రిప్ట్‌లు పెరిగాయి మరియు పెరిగాయి. మా అప్లికేషన్‌లతో పాటు పెరిగింది మరియు మార్చబడింది. ఆ సమయంలో మాకు రెండు ప్లాట్‌ఫారమ్‌లు ఉన్నాయని పరిగణనలోకి తీసుకుంటే దాదాపు 10 అప్లికేషన్‌లు ఉన్నాయి, అది దాదాపు 20 "లివింగ్" స్క్రిప్ట్‌లు.

మేము స్క్రిప్ట్‌కు కొత్త దశను జోడించాలనుకున్న ప్రతిసారీ, మేము అన్ని షెల్ స్క్రిప్ట్‌లలో ముక్కలను కాపీ-పేస్ట్ చేయాల్సి ఉంటుంది. బహుశా మనం మరింత జాగ్రత్తగా పని చేసి ఉండవచ్చు, కానీ తరచూ ఇటువంటి మార్పులు అక్షరదోషాలతో ముగిసేవి, ఇది విడుదల బృందానికి స్క్రిప్ట్‌లను సరిచేయడానికి మరియు ఈ ఆదేశాన్ని ఏ తెలివైన వ్యక్తి జోడించిందో మరియు వాస్తవానికి ఏమి చేస్తుందో తెలుసుకోవడానికి ఇది సాయంత్రాలుగా మారింది. సాధారణంగా, ఒక ప్లాట్‌ఫారమ్ కోసం అసెంబ్లీకి సంబంధించిన స్క్రిప్ట్‌లు కనీసం కొంతవరకు సమానంగా ఉన్నాయని చెప్పలేము. వారు ఖచ్చితంగా అదే పని చేసినప్పటికీ.

కొత్త అప్లికేషన్ కోసం ప్రాసెస్‌ని ప్రారంభించడానికి, ఈ స్క్రిప్ట్‌ల యొక్క “తాజా” వెర్షన్‌ని ఎంచుకుని, డీబగ్ చేసి, “అవును, ఇది పని చేస్తుంది” అని చెప్పడానికి ఒక రోజు వెచ్చించాల్సి ఉంటుంది.

2018 వేసవిలో, మేము ఇంకా అభివృద్ధి చెందుతున్న ఫాస్ట్‌లేన్ వైపు మరోసారి చూశాము.

టాస్క్ #1: అన్ని స్క్రిప్ట్ దశలను సంగ్రహించి, వాటిని ఫాస్ట్‌ఫైల్‌లో తిరిగి వ్రాయండి

మేము ప్రారంభించినప్పుడు, మా స్క్రిప్ట్‌లు జెంకిన్స్‌లోని ఒక షెల్ స్క్రిప్ట్‌లో అన్ని దశలు మరియు క్రచెస్‌లతో కూడిన ఫుట్‌క్లాత్ లాగా ఉన్నాయి. మేము ఇంకా పైపులైన్ మరియు దశలవారీగా విభజనకు మారలేదు.

మేము మా వద్ద ఉన్న వాటిని పరిశీలించాము మరియు మా CI/CD వివరణకు సరిపోయే 4 దశలను గుర్తించాము:

  • బిల్డ్ - డిపెండెన్సీలను ఇన్‌స్టాల్ చేయడం, ఆర్కైవ్‌ను సమీకరించడం,
  • పరీక్ష — డెవలపర్ యూనిట్ పరీక్షలను అమలు చేయడం, కవరేజీని లెక్కించడం,
  • సోనార్ - అన్ని లింటర్‌లను ప్రారంభించి, నివేదికలను సోనార్‌క్యూబ్‌కి పంపుతుంది,
  • deploy — ఆల్ఫా (TestFlight)కి ఒక కళాఖండాన్ని పంపడం.

మరియు మీరు వివరాల్లోకి వెళ్లకపోతే, చర్యలలో ఉపయోగించే కీలను వదిలివేస్తే, మీరు ఈ ఫాస్ట్‌ఫైల్‌ని పొందుతారు:

default_platform(:ios)

platform :ios do
  before_all do
    unlock
  end

  desc "Build stage"
  lane :build do
    match
    prepare_build
    gym
  end

  desc "Prepare build stage: carthage and cocoapods"
  lane :prepare_build do
    pathCartfile = ""
    Dir.chdir("..") do
      pathCartfile = File.join(Dir.pwd, "/Cartfile")
    end
    if File.exist?(pathCartfile)
      carthage
    end
    pathPodfile = ""
    Dir.chdir("..") do
      pathPodfile = File.join(Dir.pwd, "/Podfile")
    end
    if File.exist?(pathPodfile)
      cocoapods
    end
  end

  desc "Test stage"
  lane :test do
    scan
    xcov
  end

  desc "Sonar stage (after run test!)"
  lane :run_sonar do
    slather
    lizard
    swiftlint
    sonar
  end

  desc "Deploy to testflight stage"
  lane :deploy do
    pilot
  end

  desc "Unlock keychain"
  private_lane :unlock do
    pass = ENV['KEYCHAIN_PASSWORD']
    unlock_keychain(
      password: pass
    )
  end
end

వాస్తవానికి, మా మొదటి ఫాస్ట్‌ఫైల్ భయంకరమైనదిగా మారింది, మాకు ఇంకా అవసరమైన కొన్ని క్రచెస్ మరియు మేము ప్రత్యామ్నాయంగా ఉన్న పారామితుల సంఖ్యను పరిగణనలోకి తీసుకుంటే:

lane :build do
carthage(
  command: "update",
  use_binaries: false,
  platform: "ios",
  cache_builds: true)
cocoapods(
  clean: true,
    podfile: "./Podfile",
    use_bundle_exec: false)

gym(
  workspace: "MyApp.xcworkspace",
  configuration: "Release",
  scheme: "MyApp",
  clean: true,
  output_directory: "/build",
  output_name: "my-app.ipa")
end 

lane :deploy do
 pilot(
  username: "[email protected]",
  app_identifier: "com.example.app",
  dev_portal_team_id: "TEAM_ID_NUMBER_DEV",
  team_id: "ITS_TEAM_ID")
end

పై ఉదాహరణలో, మనం పేర్కొనవలసిన పారామితులలో కొంత భాగం మాత్రమే: ఇవి బిల్డ్ పారామితులు - స్కీమా, కాన్ఫిగరేషన్, ప్రొవిజన్ ప్రొఫైల్ పేర్లు, అలాగే పంపిణీ పారామితులు - డెవలపర్ ఖాతా యొక్క Apple ID, పాస్‌వర్డ్, అప్లికేషన్ ID మరియు మొదలైనవి పై. మొదటి ఉజ్జాయింపుగా, మేము ఈ కీలన్నింటినీ ప్రత్యేక ఫైల్‌లలో ఉంచాము - Gymfile, Matchfile и Appfile.

ఇప్పుడు జెంకిన్స్‌లో మీరు వీక్షణను అస్పష్టం చేయని మరియు కంటితో సులభంగా చదవగలిగే చిన్న ఆదేశాలను కాల్ చేయవచ్చు:

# fastlane ios <lane_name>

$ fastlane ios build
$ fastlane ios test
$ fastlane ios run_sonar
$ fastlane ios deploy

హుర్రే, మేము గొప్పవారము

నీకు ఏమి వచ్చింది? ప్రతి దశకు ఆదేశాలను క్లియర్ చేయండి. స్క్రిప్ట్‌లను శుభ్రం చేసి, ఫాస్ట్‌లేన్ ఫైల్‌లలో చక్కగా అమర్చారు. సంతోషిస్తూ, మేము డెవలపర్‌ల వద్దకు పరుగెత్తాము, వారికి అవసరమైన ప్రతిదాన్ని వారి రిపోజిటరీలకు జోడించమని కోరాము.

కానీ మేము అదే ఇబ్బందులను ఎదుర్కొంటామని మేము సమయానికి గ్రహించాము - మేము ఇప్పటికీ 20 అసెంబ్లీ స్క్రిప్ట్‌లను కలిగి ఉన్నాము, అవి ఒక మార్గం లేదా మరొకటి వారి స్వంత జీవితాన్ని గడపడం ప్రారంభిస్తాయి, వాటిని సవరించడం చాలా కష్టం, ఎందుకంటే స్క్రిప్ట్‌లు రిపోజిటరీలకు మారుతాయి, మరియు మాకు అక్కడ యాక్సెస్ లేదు. మరియు, సాధారణంగా, మా బాధను ఈ విధంగా పరిష్కరించడం సాధ్యం కాదు.

మొబైల్ CICD అనుభవం: అనేక మొబైల్ అప్లికేషన్‌ల కోసం ఒక ఫాస్ట్‌లేన్ ప్రమాణం

టాస్క్ #2: N అప్లికేషన్‌ల కోసం ఒకే Fastfileని పొందండి

ఇప్పుడు సమస్యను పరిష్కరించడం అంత కష్టం కాదని అనిపిస్తుంది - వేరియబుల్స్ సెట్ చేయండి మరియు వెళ్దాం. అవును, నిజానికి, సమస్య ఎలా పరిష్కరించబడింది. కానీ మేము దానిని చిత్తు చేసిన క్షణంలో, మాకు ఫాస్ట్‌లేన్‌లో లేదా ఫాస్ట్‌లేన్ వ్రాసిన రూబీలో లేదా నెట్‌వర్క్‌లో ఉపయోగకరమైన ఉదాహరణలు లేవు - అప్పుడు ఫాస్ట్‌లేన్ గురించి వ్రాసిన ప్రతి ఒక్కరూ ఒక అప్లికేషన్ కోసం ఒక ఉదాహరణకి పరిమితం చేయబడ్డారు. ఒక డెవలపర్.

ఫాస్ట్‌లేన్ ఎన్విరాన్‌మెంట్ వేరియబుల్స్‌ని నిర్వహించగలదు మరియు కీచైన్ పాస్‌వర్డ్‌ని సెట్ చేయడం ద్వారా మేము దీన్ని ఇప్పటికే ప్రయత్నించాము:

ENV['KEYCHAIN_PASSWORD']

మా స్క్రిప్ట్‌లను చూసిన తర్వాత, మేము సాధారణ భాగాలను గుర్తించాము:

#for build, test and deploy
APPLICATION_SCHEME_NAME=appScheme
APPLICATION_PROJECT_NAME=app.xcodeproj
APPLICATION_WORKSPACE_NAME=app.xcworkspace
APPLICATION_NAME=appName

OUTPUT_IPA_NAME=appName.ipa

#app info
APP_BUNDLE_IDENTIFIER=com.example.appName
[email protected]
TEAM_ID=ABCD1234
FASTLANE_ITC_TEAM_ID=123456789

ఇప్పుడు, ఫాస్ట్‌లేన్ ఫైల్‌లలో ఈ కీలను ఉపయోగించడం ప్రారంభించడానికి, వాటిని అక్కడ ఎలా డెలివరీ చేయాలో మనం గుర్తించాలి. ఫాస్ట్‌లేన్ దీనికి ఒక పరిష్కారాన్ని కలిగి ఉంది: dotenv ద్వారా వేరియబుల్స్ లోడ్ అవుతోంది. వివిధ ప్రయోజనాల కోసం కీలను లోడ్ చేయడం మీకు ముఖ్యమైతే, ఫాస్ట్‌లేన్ డైరెక్టరీలో అనేక కాన్ఫిగరేషన్ ఫైల్‌లను సృష్టించండి అని డాక్యుమెంటేషన్ చెబుతోంది. .env, .env.default, .env.development.

ఆపై మేము ఈ లైబ్రరీని కొద్దిగా భిన్నంగా ఉపయోగించాలని నిర్ణయించుకున్నాము. డెవలపర్‌ల రిపోజిటరీలో ఫాస్ట్‌లేన్ స్క్రిప్ట్‌లు మరియు దాని మెటా సమాచారాన్ని కాకుండా ఫైల్‌లో ఈ అప్లికేషన్ యొక్క ప్రత్యేక కీలను ఉంచుదాం .env.appName.

తాము Fastfile, Appfile, Matchfile и Gymfile, మేము దానిని ప్రత్యేక రిపోజిటరీలో దాచాము. ఇతర సేవల నుండి పాస్‌వర్డ్ కీలతో కూడిన అదనపు ఫైల్ అక్కడ దాచబడింది - .env.
మీరు ఒక ఉదాహరణను చూడవచ్చు ఇక్కడ.

మొబైల్ CICD అనుభవం: అనేక మొబైల్ అప్లికేషన్‌ల కోసం ఒక ఫాస్ట్‌లేన్ ప్రమాణం

CIలో, కాల్ పెద్దగా మారలేదు, నిర్దిష్ట అప్లికేషన్ కోసం కాన్ఫిగరేషన్ కీ జోడించబడింది:

# fastlane ios <lane_name> --env appName

$ fastlane ios build --env appName
$ fastlane ios test --env appName
$ fastlane ios run_sonar --env appName
$ fastlane ios deploy --env appName

ఆదేశాలను అమలు చేయడానికి ముందు, మేము మా రిపోజిటరీని స్క్రిప్ట్‌లతో లోడ్ చేస్తాము. అంత అందంగా కనిపించడం లేదు:

git clone [email protected]/FastlaneCICD.git fastlane_temp

cp ./fastlane_temp/fastlane/* ./fastlane/
cp ./fastlane_temp/fastlane/.env fastlane/.env

ఫాస్ట్‌ఫైల్‌ను డౌన్‌లోడ్ చేయడానికి ఫాస్ట్‌లేన్‌కు పరిష్కారం ఉన్నప్పటికీ, ప్రస్తుతానికి ఈ పరిష్కారాన్ని వదిలివేయండి చర్య import_from_git, కానీ ఇది Fastfile కోసం మాత్రమే పనిచేస్తుంది, కానీ ఇతర ఫైల్‌లకు కాదు. మీరు "నిజంగా అందంగా" కావాలనుకుంటే, మీరు మీ స్వంతంగా వ్రాయవచ్చు action.

Android అప్లికేషన్లు మరియు ReactNative కోసం ఇదే విధమైన సెట్ చేయబడింది, ఫైల్‌లు ఒకే రిపోజిటరీలో ఉన్నాయి, కానీ వివిధ శాఖలలో ఉన్నాయి iOS, android и react_native.

విడుదల బృందం కొన్ని కొత్త దశలను జోడించాలనుకున్నప్పుడు, స్క్రిప్ట్‌లో మార్పులు Gitలో MR ద్వారా రికార్డ్ చేయబడతాయి, ఇకపై విరిగిన స్క్రిప్ట్‌ల దోషుల కోసం వెతకవలసిన అవసరం లేదు మరియు సాధారణంగా, ఇప్పుడు మీరు దానిని విచ్ఛిన్నం చేయడానికి ప్రయత్నించాలి.

ఇప్పుడు ఖచ్చితంగా అంతే

గతంలో, మేము అన్ని స్క్రిప్ట్‌లను నిర్వహించడం, వాటిని నవీకరించడం మరియు నవీకరణల యొక్క అన్ని పరిణామాలను పరిష్కరించడం కోసం సమయాన్ని వెచ్చించాము. షెల్ స్క్రిప్ట్‌ల గందరగోళంలో ట్రాక్ చేయడం చాలా కష్టంగా ఉండే సాధారణ అక్షరదోషాలు విడుదలలలో లోపాలు మరియు పనికిరాని సమయానికి కారణాలు చాలా నిరాశపరిచాయి. ఇప్పుడు అలాంటి లోపాలు కనిష్టానికి తగ్గించబడ్డాయి. మార్పులు ఒకేసారి అన్ని అప్లికేషన్‌లకు అందుబాటులోకి వస్తాయి. మరియు ప్రక్రియలో కొత్త అప్లికేషన్‌ను ఉంచడానికి 15 నిమిషాలు పడుతుంది - CIలో టెంప్లేట్ పైప్‌లైన్‌ను సెటప్ చేయండి మరియు డెవలపర్ రిపోజిటరీకి కీలను జోడించండి.

ఆండ్రాయిడ్ కోసం ఫాస్ట్‌ఫైల్ మరియు అప్లికేషన్ సిగ్నేచర్‌తో ఉన్న పాయింట్ వివరించబడనట్లు కనిపిస్తోంది, కథనం ఆసక్తికరంగా ఉంటే, నేను కొనసాగింపును వ్రాస్తాను. వ్యాఖ్యలలో లేదా టెలిగ్రామ్‌లో "మీరు ఈ సమస్యను ఎలా పరిష్కరిస్తారు" అనే మీ ప్రశ్నలు లేదా సూచనలను చూసి నేను సంతోషిస్తాను బాష్కిరోవా.

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి