Creating a commit with multiple files to Github with JS on the web

मेरी साइट entirely static । यह Hugo साथ बनाया गया है और Zeit साथ होस्ट किया Zeit । मैं सेटअप के साथ बहुत खुश हूं, मुझे तत्काल बिल्ड और सुपर फास्ट सीडीएनआईडी कंटेंट डिलीवरी के पास मिलता है और मैं उन सभी चीजों को कर सकता हूं जिनकी मुझे आवश्यकता है क्योंकि मुझे किसी भी राज्य का प्रबंधन करने की आवश्यकता नहीं है।

मैंने इस साइट के लिए एक simple UI बनाया है और मेरा podcast creator भी है जो मुझे अपने podcast creator रूप से होस्ट की गई साइट पर जल्दी से नई सामग्री पोस्ट करने में सक्षम बनाता है।

इसलिए। मैंने इसे कैसे किया?

यह EditorJS संपादित सामग्री (यह साफ) और Octokat.js रेपो के लिए प्रतिबद्ध करने को बनाने के लिए और फिर मेरी ह्यूगो निर्माण करने के लिए ज़ीट के Github एकीकरण मेरी Github रेपो के खिलाफ Firebase प्रमाणीकरण का एक संयोजन है। इस सेट अप के साथ, मैं एक पूरी तरह से स्व-होस्ट किए गए स्थिर सीएमएस को सक्षम कर सकता हूं, इसी तरह एक उपयोगकर्ता वर्डप्रेस जैसे डेटाबेस समर्थित सीएमएस में पोस्ट कैसे बना सकता है।

इस पोस्ट में मैं सिर्फ इंफ्रास्ट्रक्चर के एक हिस्से पर ध्यान केंद्रित करने जा रहा हूं - जीथब को कई फाइलें देना क्योंकि मुझे काम करने में थोड़ा समय लगा।

पूरा कोड मेरे repo पर देखा जा सकता है।

यदि आप एक वेब यूआई का निर्माण कर रहे हैं, जिसे सीधे जीथब करने की आवश्यकता है, तो मुझे जो सबसे अच्छा पुस्तकालय मिला है, वह है ऑक्टोकैट - यह कोर के साथ काम करता है और यह जीथब एपीआई की पूरी एपीआई सतह को संभालने के लिए लगता है।

Git एक जटिल जानवर हो सकता है जब यह समझ में आता है कि पेड़, शाखाएं और अन्य टुकड़े कैसे काम करते हैं इसलिए मैंने कुछ फैसले लिए जिससे यह आसान हो गया।

  1. मैं केवल मास्टर शाखा में काम करने में सक्षम heads/master जिसे heads/master नाम से जाना जाता है।
  2. मुझे पता चल जाएगा कि कुछ फाइलें कहाँ संग्रहीत होंगी (ह्यूगो ने मुझे एक विशिष्ट निर्देशिका संरचना के लिए बाध्य किया है)

इसे ध्यान में रखते हुए, एकाधिक फ़ाइलों के साथ एक कमेटी बनाने की सामान्य प्रक्रिया इस प्रकार है:

रेपो का संदर्भ लें।

  1. heads/master शाखा पर पेड़ की नोक का संदर्भ heads/master
  2. प्रत्येक फ़ाइल के लिए जिसे हम एक blob बनाना चाहते हैं और फिर एक सरणी में sha पहचानकर्ता, पथ, मोड के संदर्भों को संग्रहीत करते हैं।
  3. एक नया tree बनाएं, जिसमें heads/master पेड़ की नोक के संदर्भ में जोड़ने के लिए सभी heads/master , और इस पेड़ पर नए sha पॉइंटर को स्टोर करें।
  4. इस नए पेड़ की ओर heads/master करने वाली एक heads/master और फिर heads/master ब्रांच पर जाएं।

कोड बहुत उस प्रवाह का अनुसरण करता है। क्योंकि मैं कुछ निविष्टियों के लिए पथ संरचना ग्रहण कर सकता हूं, इसलिए मुझे फ़ाइलों के लिए किसी भी जटिल UI या प्रबंधन का निर्माण करने की आवश्यकता नहीं है।

const createCommit = async (repositoryUrl, filename, data, images, commitMessage, recording) => {
  try {
    const token = localStorage.getItem('accessToken');
    const github = new Octokat({ 'token': token });
    const [user, repoName] = repositoryUrl.split('/');

    if(user === null || repoName === null) {
      alert('Please specifiy a repo');
      return;
    }
    
    const markdownPath = `site/content/${filename}.markdown`.toLowerCase();
    let repo = await github.repos(user, repoName).fetch();
    let main = await repo.git.refs('heads/master').fetch();
    let treeItems = [];

    for(let image of images) {
      let imageGit = await repo.git.blobs.create({ content: image.data, encoding: 'base64' });
      let imagePath = `site/static/images/${image.name}`.toLowerCase();
      treeItems.push({
        path: imagePath,
        sha: imageGit.sha,
        mode: "100644",
        type: "blob"
        });
    }

    if (recording) {
      let audioGit = await repo.git.blobs.create({ content: recording.data, encoding: 'base64' });
      let audioPath = `site/static/audio/${recording.name}.${recording.extension}`.toLowerCase();
      treeItems.push({
        path: audioPath,
        sha: audioGit.sha,
        mode: "100644",
        type: "blob"
        });
    }

    let markdownFile = await repo.git.blobs.create({ content: btoa(jsonEncode(data)), encoding: 'base64' });
    treeItems.push({
      path: markdownPath,
      sha: markdownFile.sha,
      mode: "100644",
      type: "blob"
    });

    let tree = await repo.git.trees.create({
      tree: treeItems,
      base_tree: main.object.sha
    });
  
    let commit = await repo.git.commits.create({
      message: `Created via Web - ${commitMessage}`,
      tree: tree.sha,
      parents: [main.object.sha]});

    main.update({sha: commit.sha})

    logToToast('Posted');
  } catch (err) {
    console.error(err);
    logToToast(err);
  }
}

मुझे पता है कि क्या आपने स्थैतिक होस्टिंग के साथ ऐसा ही कुछ किया है। मैं बहुत उत्साहित हूं कि मैं एक आधुनिक फ्रंटएंड बना सकता हूं जो एक पूरी तरह से सर्वर-कम होस्टिंग इन्फ्रास्ट्रक्चर है।

Zeit के बारे में क्या?

खैर, यह अभी थोड़े स्वचालित है। मैं ह्यूगो कमांड को चलाने के लिए static-builder का उपयोग करता static-builder और यह बहुत ज्यादा है। :)

About Me: Paul Kinlan

I lead the Chrome Developer Relations team at Google.

We want people to have the best experience possible on the web without having to install a native app or produce content in a walled garden.

Our team tries to make it easier for developers to build on the web by supporting every Chrome release, creating great content to support developers on web.dev, contributing to MDN, helping to improve browser compatibility, and some of the best developer tools like Lighthouse, Workbox, Squoosh to name just a few.