<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mihindu Ranasinghe</title>
    <description>The latest articles on DEV Community by Mihindu Ranasinghe (@mihinduranasinghe).</description>
    <link>https://dev.to/mihinduranasinghe</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F318770%2F890bddec-e7ef-45e5-bd6a-04119d5f33bd.png</url>
      <title>DEV Community: Mihindu Ranasinghe</title>
      <link>https://dev.to/mihinduranasinghe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mihinduranasinghe"/>
    <language>en</language>
    <item>
      <title>Why AI Systems Become Expensive: Tokenization, Chunking, and Retrieval Design in the Cloud (AWS)</title>
      <dc:creator>Mihindu Ranasinghe</dc:creator>
      <pubDate>Sat, 07 Mar 2026 15:40:08 +0000</pubDate>
      <link>https://dev.to/mihinduranasinghe/why-ai-systems-become-expensive-tokenization-chunking-and-retrieval-design-in-the-cloud-aws-2g17</link>
      <guid>https://dev.to/mihinduranasinghe/why-ai-systems-become-expensive-tokenization-chunking-and-retrieval-design-in-the-cloud-aws-2g17</guid>
      <description>&lt;p&gt;When building modern AI knowledge systems, discussions often jump directly to prompts, retrieval pipelines, or model selection. However, long before a model generates an answer, something more fundamental happens that your data must be transformed into a format that models can understand and retrieve efficiently.&lt;/p&gt;

&lt;p&gt;This transformation typically involves several foundational steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Tokenization&lt;/strong&gt; – Converting raw text into model-readable units&lt;br&gt;
&lt;strong&gt;2. Chunking&lt;/strong&gt; – Splitting documents into manageable segments&lt;br&gt;
&lt;strong&gt;3. Vectorization&lt;/strong&gt; – Converting text into embeddings&lt;br&gt;
&lt;strong&gt;4. Indexing&lt;/strong&gt; – Storing vectors for efficient similarity search&lt;/p&gt;

&lt;p&gt;These steps form the foundation of retrieval-based AI systems, and design decisions at this stage often have a greater impact on system performance than prompt engineering or model tuning.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;These architectural considerations are also increasingly relevant for modern AI development tools such as Claude Code, OpenAI Codex–based systems, and other AI-powered coding assistants. Although these tools may appear to operate purely through conversational prompts, they often rely on similar retrieval pipelines under the hood, indexing codebases, documentation, and contextual information before generating responses. As a result, the same factors discussed in this article, such as tokenization, chunking strategies, embeddings, and retrieval design, can significantly influence both the performance and the token consumption of these systems.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In this article, we explore how these processes work together and how they can be implemented using Amazon Bedrock and Amazon OpenSearch Service.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Retrieval Pipeline Begins Before Retrieval
&lt;/h3&gt;

&lt;p&gt;Before a model retrieves or generates information, data must first pass through a preparation pipeline.&lt;/p&gt;

&lt;p&gt;Each stage introduces trade-offs affecting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieval accuracy&lt;/li&gt;
&lt;li&gt;Latency&lt;/li&gt;
&lt;li&gt;Operational cost&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Designing this pipeline carefully is essential for scalable GenAI systems.&lt;/p&gt;


&lt;h2&gt;
  
  
  Tokenization: How Models Read Text
&lt;/h2&gt;

&lt;p&gt;Large language models do not process text directly. Instead, they operate on tokens, which are smaller units derived from text.&lt;/p&gt;

&lt;p&gt;Tokens may represent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whole words&lt;/li&gt;
&lt;li&gt;Parts of words&lt;/li&gt;
&lt;li&gt;Punctuation&lt;/li&gt;
&lt;li&gt;Whitespace&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;code&gt;Cloud computing enables scalable AI systems.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;might be tokenized as:&lt;br&gt;
&lt;code&gt;["Cloud", " computing", " enables", " scalable", " AI", " systems", "."]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Tokenization is necessary because models operate within fixed context windows, defined by the maximum number of tokens they can process at once.&lt;/p&gt;

&lt;p&gt;However, token counts vary depending on the model's tokenizer.&lt;/p&gt;
&lt;h2&gt;
  
  
  Tokenization Algorithms
&lt;/h2&gt;

&lt;p&gt;Tokenization is performed using trained algorithms rather than simple whitespace splitting.&lt;/p&gt;

&lt;p&gt;Common approaches include:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Algorithm&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Byte Pair Encoding (BPE)&lt;/td&gt;
&lt;td&gt;Merges frequently occurring character pairs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WordPiece&lt;/td&gt;
&lt;td&gt;Used in many transformer-based models&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unigram Language Model&lt;/td&gt;
&lt;td&gt;Probabilistic token selection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SentencePiece&lt;/td&gt;
&lt;td&gt;Language-agnostic tokenizer framework&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Many modern models rely on Byte Pair Encoding or similar subword tokenization techniques (Sennrich et al., 2016).&lt;/p&gt;

&lt;p&gt;Example: Byte Pair Encoding&lt;/p&gt;

&lt;p&gt;Consider the word: &lt;code&gt;tokenization&lt;/code&gt;, A BPE tokenizer may split it as:&lt;br&gt;
&lt;code&gt;["token", "ization"]&lt;/code&gt; or &lt;code&gt;["token", "iz", "ation"]&lt;/code&gt; depending on how the tokenizer vocabulary was learned.&lt;/p&gt;

&lt;p&gt;Subword tokenization allows models to represent rare or unseen words efficiently without requiring extremely large vocabularies.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Tokenization Matters
&lt;/h2&gt;

&lt;p&gt;Tokenization affects several key aspects of AI system design.&lt;/p&gt;
&lt;h4&gt;
  
  
  Context Window Limits
&lt;/h4&gt;

&lt;p&gt;Models can only process a limited number of tokens at once. Depending on the model, context windows may range from thousands to hundreds of thousands of tokens.&lt;/p&gt;

&lt;p&gt;Large documents therefore need to be split into smaller chunks before processing.&lt;/p&gt;
&lt;h4&gt;
  
  
  Cost
&lt;/h4&gt;

&lt;p&gt;Many generative AI platforms charge based on token usage. When generating embeddings or performing inference with &lt;a href="https://aws.amazon.com/bedrock/" rel="noopener noreferrer"&gt;Amazon Bedrock&lt;/a&gt;, token counts directly influence operational costs.&lt;/p&gt;
&lt;h4&gt;
  
  
  Retrieval Quality
&lt;/h4&gt;

&lt;p&gt;Chunk sizes and overlaps are typically defined in tokens. Tokenization therefore influences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chunk boundaries&lt;/li&gt;
&lt;li&gt;Embedding context&lt;/li&gt;
&lt;li&gt;Retrieval precision&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Token Cost Optimization in GenAI Pipelines
&lt;/h2&gt;

&lt;p&gt;In production systems, whether powering AI assistants, coding copilots, or knowledge retrieval pipelines, token usage is not just a technical constraint, it is also a major cost driver. Most generative AI platforms charge based on the number of input and output tokens processed. When models are accessed through services such as Amazon Bedrock, inefficient prompt construction or overly large context windows can significantly increase operational cost.&lt;/p&gt;

&lt;p&gt;Token usage grows quickly at scale. For example, a system sending 2,000 tokens per request and serving 10,000 requests per day processes 20 million tokens daily. Even small inefficiencies in chunking or retrieval strategies can therefore become expensive.&lt;/p&gt;

&lt;p&gt;Design decisions such as chunk size, overlap, and retrieval precision directly influence token consumption. Smaller, well-structured chunks combined with accurate vector retrieval (for example using Amazon OpenSearch Service) help ensure that only the most relevant context is sent to the model.&lt;/p&gt;

&lt;p&gt;Treating token efficiency as an architectural concern, not just a billing metric, can significantly improve the scalability and cost-efficiency of GenAI systems.&lt;/p&gt;


&lt;h2&gt;
  
  
  Chunking: Preparing Documents for Retrieval
&lt;/h2&gt;

&lt;p&gt;Chunking refers to the process of splitting large documents into smaller segments prior to indexing.&lt;/p&gt;

&lt;p&gt;Effective chunking improves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieval accuracy&lt;/li&gt;
&lt;li&gt;Semantic coherence of embeddings&lt;/li&gt;
&lt;li&gt;Query relevance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Poor chunking may result in fragmented information or irrelevant context.&lt;/p&gt;

&lt;p&gt;Several strategies are commonly used.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Standard Chunking
&lt;/h2&gt;

&lt;p&gt;The simplest method is fixed-size chunking, where text is split based on a predetermined token length.&lt;/p&gt;

&lt;p&gt;Example configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Chunk size: 300 tokens
Overlap: 20%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Overlap ensures that information spanning chunk boundaries remains available.&lt;/p&gt;

&lt;p&gt;Typical parameters include:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chunk size&lt;/td&gt;
&lt;td&gt;Number of tokens per chunk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Overlap&lt;/td&gt;
&lt;td&gt;Shared tokens between chunks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Many systems default to approximately 300 tokens per chunk, although optimal sizes vary depending on document structure and query patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Hierarchical Chunking
&lt;/h2&gt;

&lt;p&gt;Hierarchical chunking preserves document structure by splitting text into nested segments.&lt;/p&gt;

&lt;p&gt;Example structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Document
 ├── Section
 │    ├── Paragraph
 │    │     ├── Sentence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This enables retrieval at multiple levels of granularity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fine-grained paragraph retrieval&lt;/li&gt;
&lt;li&gt;broader section-level context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hierarchical chunking is particularly useful for large technical documentation or knowledge bases.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Semantic Chunking
&lt;/h2&gt;

&lt;p&gt;Traditional chunking splits text mechanically. Semantic chunking instead splits text based on meaning and topic boundaries.&lt;/p&gt;

&lt;p&gt;Instead of dividing text every fixed number of tokens, semantic chunking analyzes content to group sentences that represent a coherent concept.&lt;/p&gt;

&lt;p&gt;Foundation models available &lt;a href="https://docs.aws.amazon.com/bedrock/latest/APIReference/API_agent_SemanticChunkingConfiguration.html" rel="noopener noreferrer"&gt;through Amazon Bedrock&lt;/a&gt; can assist in identifying semantic boundaries.&lt;/p&gt;

&lt;p&gt;This often produces more meaningful chunks, improving retrieval quality.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vectorization: Converting Text into Embeddings
&lt;/h2&gt;

&lt;p&gt;After chunking, each segment is converted into a vector embedding.&lt;/p&gt;

&lt;p&gt;Embeddings represent text as numerical vectors capturing semantic meaning.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;code&gt;"cloud infrastructure"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;might become:&lt;br&gt;
&lt;code&gt;[0.43, 0.24, 0.54, 0.12, 0.53]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Embeddings allow systems to compare semantic similarity between text segments.&lt;/p&gt;

&lt;p&gt;Embedding generation can be performed using models provided through Amazon Bedrock.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimizing Embeddings
&lt;/h2&gt;

&lt;p&gt;Embedding design has a direct impact on performance and cost.&lt;/p&gt;

&lt;p&gt;Embeddings vary in Vector Dimensionality, and higher-dimensional vectors can capture more semantic nuance but require more storage and computational resources.&lt;/p&gt;




&lt;h2&gt;
  
  
  Indexing Embeddings for Retrieval
&lt;/h2&gt;

&lt;p&gt;Once embeddings are generated, they must be stored in a structure supporting efficient similarity search.&lt;/p&gt;

&lt;p&gt;Vector databases achieve this using Approximate Nearest Neighbor (ANN) algorithms, which allow searching across millions of vectors efficiently (Aumüller et al., 2020).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/opensearch-service/latest/developerguide/vector-search.html" rel="noopener noreferrer"&gt;Amazon OpenSearch Service supports vector&lt;/a&gt; search capabilities using ANN indexing.&lt;/p&gt;

&lt;p&gt;Typical workflow:&lt;/p&gt;

&lt;h2&gt;
  
  
  Example AWS Architecture
&lt;/h2&gt;

&lt;p&gt;This architecture separates concerns across:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ingestion&lt;/li&gt;
&lt;li&gt;Processing&lt;/li&gt;
&lt;li&gt;Embedding generation&lt;/li&gt;
&lt;li&gt;Vector indexing&lt;/li&gt;
&lt;li&gt;Retrieval&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example: Generating Embeddings with AWS Bedrock
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import boto3
import json

bedrock = boto3.client("bedrock-runtime")

text = "Cloud architecture improves scalability and resilience."

response = bedrock.invoke_model(
    modelId="amazon.titan-embed-text-v1",
    body=json.dumps({"inputText": text})
)

embedding = json.loads(response['body'].read())

print(embedding)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The generated vector can then be indexed in Amazon OpenSearch Service for similarity search.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tokenization, chunking, vectorization, and indexing form the core infrastructure of retrieval-based AI systems.&lt;/li&gt;
&lt;li&gt;Although much attention is given to models and prompt engineering, the effectiveness of an AI system often depends more on how knowledge is structured and indexed before retrieval.&lt;/li&gt;
&lt;li&gt;Platforms such as Amazon Bedrock and Amazon OpenSearch Service provide powerful building blocks for implementing these pipelines.&lt;/li&gt;
&lt;li&gt;However, achieving high-quality retrieval ultimately depends on designing the data preparation process thoughtfully&lt;/li&gt;
&lt;li&gt;Efficient tokenization and chunking strategies not only improve retrieval quality but also play a critical role in controlling token consumption and operational cost in large-scale GenAI systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Sennrich, R., Haddow, B., &amp;amp; Birch, A. (2016). Neural Machine Translation of Rare Words with Subword Units. ACL.&lt;/li&gt;
&lt;li&gt;Vaswani, A. et al. (2017). Attention Is All You Need. NeurIPS.&lt;/li&gt;
&lt;li&gt;Kudo, T., &amp;amp; Richardson, J. (2018). SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing.&lt;/li&gt;
&lt;li&gt;Aumüller, M., Bernhardsson, E., &amp;amp; Faithfull, A. (2020). ANN-Benchmarks: A Benchmarking Tool for Approximate Nearest Neighbor Algorithms.&lt;/li&gt;
&lt;li&gt;Salton, G., &amp;amp; Buckley, C. (1988). Term-Weighting Approaches in Automatic Text Retrieval.&lt;/li&gt;
&lt;li&gt;AWS Documentation – Amazon Bedrock&lt;/li&gt;
&lt;li&gt;AWS Documentation – Amazon OpenSearch Vector Search&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're building AI systems today, optimizing tokenization and chunking strategies early can save significant cost and complexity later.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>llm</category>
    </item>
    <item>
      <title>Future of User Interface Design</title>
      <dc:creator>Mihindu Ranasinghe</dc:creator>
      <pubDate>Wed, 06 Apr 2022 12:33:01 +0000</pubDate>
      <link>https://dev.to/mihinduranasinghe/future-of-user-interface-design-j6c</link>
      <guid>https://dev.to/mihinduranasinghe/future-of-user-interface-design-j6c</guid>
      <description>&lt;p&gt;The next generation of User Interface (UI) design tools and how those UI trends impact on day to day life is really important. Before dive in to deep let’s see what user interface (UI) design is. UI can be defined as every visual aspect of a smart device, that enables the user to interact with the technology in a largely seamless manner. User interface (UI) design, also known as the process of creating user interfaces for machines and software, such as computers, household appliances, mobile phones, and other electronic devices, with the goal of increasing the ability to interact with them and improving the user experience. These days, design and user experience of applications are important than ever. &lt;/p&gt;

&lt;p&gt;UI designing is now rapidly improving in the industry. Engineers are working on improves the look and feel and adding values to the products by developing better UIs. So it's time to look into upcoming designs shifts and trends and some incredible future UI designs.&lt;/p&gt;

&lt;h2&gt;
  
  
  User interface designs in future
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Voice User Interface
&lt;/h3&gt;

&lt;p&gt;Voice User Interface allows users to interact with a system through speech commands. Examples of VUI are virtual assistants, such as Siri, Google Assistant, and Alexa. With the better machine learning capability, the VUI comonad is now similar to human language. The advantage of VUI is work with voice interfaces is faster and saves time. For example, while we working on something we can provide voice commands without holding the current task.&lt;/p&gt;

&lt;h3&gt;
  
  
  Brain computer interface
&lt;/h3&gt;

&lt;p&gt;In simpler words, a brain computer interface (BCI), also known as a direct neural interface or a brain machine interface, is a tool that allows a person (their brain) to communicate with a system (an external technology). Neurons in our brain send and receive signals from other nerve cells. These neurons produce brain waves, which operate the system in the brain-computer interface. The BCI captures brain waves and delivers them to a computer system to complete the work at hand. The brain generates electric impulses in response to our ideas, and each thought has its own brain wave pattern. The wave signal is used to control an object and express a concept.&lt;/p&gt;

&lt;h3&gt;
  
  
  Augmented Reality (AR)
&lt;/h3&gt;

&lt;p&gt;Augmented reality is no longer a cutting-edge technology. Despite the fact that adoption is still in its early stages, companies have used the AR experience in a variety of apps, games, glasses, and systems. It has yet to reach its full potential, however.&lt;br&gt;
AR augments the real-world environment by adding perceptual simulated or virtual material via computer-generated input, transforming objects in our environment into an interactive digital experience. It has expanded into a variety of industries, including healthcare, retail, gaming, entertainment, hospitality, tourism, education, design, and many more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dynamic Color Palets
&lt;/h3&gt;

&lt;p&gt;Most mobile phones, adding feature of dynamic color palettes and helps the users to customize their phones and create a good-looking and harmonious result. Designers should keep dynamic color palettes in mind when it comes to UI. From 2022 onwards, such palettes have a high chance of being a staple on Android as more brands will have their own iteration of this trend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Holographic user interfaces
&lt;/h3&gt;

&lt;p&gt;A holographic display is a form of display that creates a virtual three-dimensional representation of an object via light diffraction. Holograms differ from other types of 3D imaging in that they do not require the use of special glasses or other external equipment to view the image. People have been able to express their views and imaginations through the medium of science fiction.&lt;/p&gt;

&lt;h3&gt;
  
  
  Biometric and cybernetic interaces
&lt;/h3&gt;

&lt;p&gt;Cybernetics is a term used in computing to describe robotic systems, as well as their control and command. Biometrics, on the other hand, refers to biological markers that are present in every human being (as well as all other living things) and are generally unique to each individual. Fingerprint and retina scanners, for example, are frequently employed for security purposes.&lt;br&gt;
Here are a few current biometric and cybernetic interface projects. For example, warfighter physiological, Status monitoring, fingerprint scanners, Digital glass...etc&lt;/p&gt;

&lt;p&gt;Not only the explained above, users can gain many advantages in the future by using the interactive user interfaces. New technologies in UI facilitate users to do their tasks without wasting time in an enjoyable manner. When people looking at a screen/virtual object for a longer period human eyes may get tried. People may get isolated with their devices.&lt;/p&gt;

&lt;p&gt;Designers should keep in mind the important elements that will keep the end users tight to the screen or the device.&lt;/p&gt;

</description>
      <category>ui</category>
      <category>ux</category>
      <category>futureofui</category>
    </item>
    <item>
      <title>WSO2 API Cloud - Adding mediation sequences, documents and API thumbnails using CLI Tool.</title>
      <dc:creator>Mihindu Ranasinghe</dc:creator>
      <pubDate>Sun, 24 Jan 2021 14:07:41 +0000</pubDate>
      <link>https://dev.to/mihinduranasinghe/wso2-api-cloud-adding-mediation-sequences-documents-and-api-thumbnails-from-cli-tool-3l5h</link>
      <guid>https://dev.to/mihinduranasinghe/wso2-api-cloud-adding-mediation-sequences-documents-and-api-thumbnails-from-cli-tool-3l5h</guid>
      <description>&lt;p&gt;WSO2 API Cloud delivers an enterprise-ready solution for creating, publishing, and managing all aspects of an API and its lifecycle. To register and get started with WSO2 API Cloud, go to &lt;a href="http://wso2.com/cloud/api-cloud/" rel="noopener noreferrer"&gt;http://wso2.com/cloud/api-cloud/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my previous article, I was focusing on Designing, Initializing and Deploying APIs to the WSO2 API Cloud &lt;strong&gt;from the command line&lt;/strong&gt; using the &lt;strong&gt;APIMCLI tool&lt;/strong&gt;. &lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Previous Article&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/mihinduranasinghe/wso2-api-cloud-projects-initialization-using-the-cli-tool-9oa"&gt;WSO2 API Cloud projects initialization and deployment using the CLI Tool&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;



&lt;h4&gt;
  
  
  In this article, we are focusing on adding mediation sequences, documents and API thumbnails &lt;strong&gt;from the command line&lt;/strong&gt; using the &lt;strong&gt;APIMCLI tool&lt;/strong&gt;, for APIs in the &lt;strong&gt;WSO2 API Cloud&lt;/strong&gt;.
&lt;/h4&gt;

&lt;p&gt;You can follow the same development environment configuration approach which I have explained in my &lt;a href="https://dev.to/mihinduranasinghe/wso2-api-cloud-projects-initialization-using-the-cli-tool-9oa"&gt;previous article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once an API project is initialized and replaced the api.yaml file and swagger.json file with our actual files [EX &lt;a href="https://gist.github.com/mihinduranasinghe/6285853c3f186b107e9bddc4d550e16d" rel="noopener noreferrer"&gt;api.yaml&lt;/a&gt;, &lt;a href="https://gist.github.com/mihinduranasinghe/0b083375f1fea5bcc03f7737804dc933" rel="noopener noreferrer"&gt;swagger.json&lt;/a&gt;], I deployed the API using the CLI Tool to the WSO2 API Cloud platform as below : &lt;/p&gt;

&lt;p&gt;The deployment approach was clearly explained in the &lt;a href="https://dev.to/mihinduranasinghe/wso2-api-cloud-projects-initialization-using-the-cli-tool-9oa"&gt;previous article&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkmpjixv2ps30x4mdsx9n.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkmpjixv2ps30x4mdsx9n.PNG" alt="Alt Text" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Adding mediation sequences from CLI.&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;An API hosted in WSO2 API Cloud receives requests sent from your consumer applications to your backend, and then sends the responses from the backend to you. The default flow of events of an API hosted in WSO2 API Cloud is depicted in the diagram below.&lt;/p&gt;

&lt;p&gt;If you need to modify or transform the requests and responses of your API, you need to engage a message mediation that intercepts the default flow. The API Gateway has a default mediation flow, which you can extend using mediation policies. You can create a custom mediation policy manually, or using a tool, and then engage it with the API. This will enable you to modify the default mediation flow for different use cases according to your requirement.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi9xo55o1j5nnfmg8e6o7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi9xo55o1j5nnfmg8e6o7.png" alt="Alt Text" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://cloud.docs.wso2.com/en/latest/learn/message-mediation/add-a-sample-mediation-sequence/" rel="noopener noreferrer"&gt;Learn more&lt;/a&gt; about WSO2 API Message Mediation Policies. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://cloud.docs.wso2.com/en/latest/learn/message-mediation/add-a-custom-sequence-to-your-api/" rel="noopener noreferrer"&gt;Here&lt;/a&gt; you can find out how to add mediation sequence policies from the WSO2 API Cloud &lt;strong&gt;Web UI&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  &lt;u&gt;Let's see how we can do this with CLI&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt; First of all you need to have prepared your &lt;strong&gt;in-flow&lt;/strong&gt;, &lt;strong&gt;out-flow&lt;/strong&gt; and &lt;br&gt;
&lt;strong&gt;fault-flow&lt;/strong&gt; Custom &lt;strong&gt;Mediation Policy files (.xml)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt; Here I have attached some sample sequence files for you to get hands-on experience and move forward with this article.  &lt;/p&gt;

&lt;p&gt;Download &lt;a href="(https://drive.google.com/file/d/1hL_dcdA7men3XPZfsrerqVyFEnidFLKj/view?usp=sharing)"&gt;in-sequence&lt;/a&gt; , &lt;a href="https://drive.google.com/file/d/1tAJCH0b8qmdFW84hNb38TsY4JwKa90Bk/view?usp=sharing" rel="noopener noreferrer"&gt;out-sequence&lt;/a&gt;, &lt;a href="https://drive.google.com/file/d/1RJtoRQCKsgDKFtRZSFDFG7nT1GizCjKa/view?usp=sharing" rel="noopener noreferrer"&gt;fault-sequence&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt; You need to create a folder with the name of &lt;strong&gt;"Custom"&lt;/strong&gt;, inside every sequence directory in your API project folder structure and you have to keep your respective &lt;strong&gt;.XML&lt;/strong&gt; files inside respective &lt;strong&gt;Custom&lt;/strong&gt; folders.&lt;/p&gt;

&lt;p&gt;As below :&lt;/p&gt;

&lt;p&gt;SampleStore&lt;br&gt;
│         ── api_params.yaml&lt;br&gt;
│   ├── Docs&lt;br&gt;
│   ├── Image&lt;br&gt;
│   ├── Meta-information&lt;br&gt;
│----------         ├── api.yaml&lt;br&gt;
│----------             └── swagger.yaml&lt;br&gt;
│   └── Sequences&lt;br&gt;
│----------        ├── in-sequence&lt;br&gt;
│--------------------         └── Custom&lt;br&gt;
│------------------------------               └── &lt;a href="https://drive.google.com/file/d/1hL_dcdA7men3XPZfsrerqVyFEnidFLKj/view?usp=sharing" rel="noopener noreferrer"&gt;in-seq.xml&lt;/a&gt;&lt;br&gt;
│----------        ├── out-sequence&lt;br&gt;
│--------------------         └── Custom&lt;br&gt;
│------------------------------               └── &lt;a href="https://drive.google.com/file/d/1tAJCH0b8qmdFW84hNb38TsY4JwKa90Bk/view?usp=sharing" rel="noopener noreferrer"&gt;out-seq.xml&lt;/a&gt;&lt;br&gt;
│----------        └── fault-sequence&lt;br&gt;
│--------------------         └── Custom&lt;br&gt;
│------------------------------                   └── &lt;a href="https://drive.google.com/file/d/1RJtoRQCKsgDKFtRZSFDFG7nT1GizCjKa/view?usp=sharing" rel="noopener noreferrer"&gt;fault-seq.xml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.&lt;/strong&gt; Then you need to enable custom mediation sequences in the API definition &lt;strong&gt;api.yaml&lt;/strong&gt; file as well.&lt;/p&gt;

&lt;p&gt;Just add these keys to the &lt;strong&gt;api.yaml&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;# Mediation Sequence&lt;/span&gt;
inSequence: in_seq
outSequence: out_seq
faultSequence: fault_seq

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h6&gt;
  
  
  Note that you can add and keep multiple sequence files in the custom folder and you can enable which one to be considered with these keys in api.yaml
&lt;/h6&gt;

&lt;p&gt;&lt;strong&gt;5.&lt;/strong&gt; Finally you need to &lt;strong&gt;log into the targeted tenant from the CLI&lt;/strong&gt; as I explained in &lt;a href="https://dev.to/mihinduranasinghe/wso2-api-cloud-projects-initialization-using-the-cli-tool-9oa"&gt;previous article&lt;/a&gt;, and &lt;strong&gt;import the API to the Targeted WSO2 API Cloud Tenant&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#apimcli login &amp;lt;Environment&amp;gt; -u &amp;lt;Username&amp;gt; -p &amp;lt;Password&amp;gt; &lt;/span&gt;
apimcli login wso2apicloud &lt;span class="nt"&gt;-u&lt;/span&gt; mihindu@wso2.com@development &lt;span class="nt"&gt;-p&lt;/span&gt; PASS54687 &lt;span class="nt"&gt;-k&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also you can login like this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;#apimcli login &amp;lt;Environment&amp;gt; &lt;/span&gt;
apimcli login wso2apicloud
Username: mihindu@wso2.com@development
Password:

Logged into wso2apicloud environment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After logging in to the targeted tenant, you can import the API using the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
apimcli import-api &lt;span class="nt"&gt;-f&lt;/span&gt; ./path/SampleStore &lt;span class="nt"&gt;-e&lt;/span&gt; wso2apicloud &lt;span class="nt"&gt;--preserve-provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="nt"&gt;--update&lt;/span&gt; &lt;span class="nt"&gt;--verbose&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h6&gt;
  
  
  Go back to WSO2 API Cloud Web Platform and you can confirm that your changes have been updated in web UI successfully like this.
&lt;/h6&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3qyhntazamffxo5viyl2.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3qyhntazamffxo5viyl2.PNG" alt="Alt Text" width="800" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Adding API Documents from the CLI.&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;WSO2 API Cloud enables you to upload documentations to your API projects from the Web UI.&lt;/p&gt;

&lt;h4&gt;
  
  
  Let's see how we can add documents to Cloud API Projects using the CLI tool.
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt; You need to have prepared the documents that you want to upload to your API Project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt; Keep your documents in the following directory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SampleStore &amp;gt; Docs &amp;gt; FileContents &amp;gt; ...&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SampleStore&lt;br&gt;
│         ── api_params.yaml&lt;br&gt;
│   ├── Docs&lt;br&gt;
│----------    ├── FileContents&lt;br&gt;
│--------------------             └── doc1.md&lt;br&gt;
│----------    └── docs.json&lt;br&gt;
│   ├── Image&lt;br&gt;
│   ├── Meta-information&lt;br&gt;
│----------         ├── api.yaml&lt;br&gt;
│----------             └── swagger.yaml&lt;br&gt;
│   └── Sequences&lt;br&gt;
│----------        ├── in-sequence&lt;br&gt;
│----------        ├── out-sequence&lt;br&gt;
│----------        └── fault-sequence&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt; Then you need to create and maintain a &lt;strong&gt;docs.json&lt;/strong&gt; file to &lt;strong&gt;configure the documents&lt;/strong&gt; with the API Cloud you added to the above directory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SampleStore &amp;gt; Docs &amp;gt; docs.json&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here you can maintain a seperate object for each and every document you added and configure  &lt;strong&gt;id,name,summary,sourceType,visibility,lastUpdate,filePath&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"61d20220-9b81-427f-a189-db933b06a070"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HOWTO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ReadMe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ReadMe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"sourceType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"FILE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"visibility"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"API_LEVEL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lastUpdated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Jan 13, 2021 9:45:43 PM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"filePath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"README.md"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5.&lt;/strong&gt; Then you need to enable this key like below in &lt;strong&gt;api.yaml&lt;/strong&gt; API definition as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="c1"&gt;# Enabling Documents Adding&lt;/span&gt;
&lt;span class="na"&gt;documents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5.&lt;/strong&gt; Finally again you need to &lt;strong&gt;log into the targeted tenant from the CLI&lt;/strong&gt; as I explained above, and &lt;strong&gt;import the API to the Targeted WSO2 API Cloud Tenant&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
apimcli import-api &lt;span class="nt"&gt;-f&lt;/span&gt; ./path/SampleStore &lt;span class="nt"&gt;-e&lt;/span&gt; wso2apicloud &lt;span class="nt"&gt;--preserve-provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="nt"&gt;--update&lt;/span&gt; &lt;span class="nt"&gt;--verbose&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h6&gt;
  
  
  Go back to WSO2 API Cloud Web Platform and you can confirm that your documents have been updated in web UI successfully like this.
&lt;/h6&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe05maxhmmjdtyn25zc2j.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe05maxhmmjdtyn25zc2j.PNG" alt="Alt Text" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Adding API Project Thumbnails from the CLI.&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You can upload API Project Thumbnails from the WSO2 API Cloud Web UI as usual.&lt;/p&gt;

&lt;p&gt;Here I will show you how you can add a thumbnail using the CLI tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt; There are few standard wso2 guidelines you need to follow when setting up a thumbnail image. (Download sample &lt;a href="https://drive.google.com/file/d/1ARtaBrJUmrclDv4-YTNHMWLtMANZdqTO/view?usp=sharing" rel="noopener noreferrer"&gt;icon.jpeg&lt;/a&gt;)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thumbnail image must be in the size of &lt;strong&gt;100px X 100px&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Thumbnail image must be renamed as &lt;em&gt;"ïcon.jpeg"&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt; Then you need to place the image in the following directory.&lt;/p&gt;

&lt;p&gt;SampleStore&lt;br&gt;
│   ├── Image&lt;br&gt;
│----------    └── &lt;a href="https://drive.google.com/file/d/1ARtaBrJUmrclDv4-YTNHMWLtMANZdqTO/view?usp=sharing" rel="noopener noreferrer"&gt;icon.jpeg&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt; Finally again you need to &lt;strong&gt;log into the targeted tenant from the CLI&lt;/strong&gt; as I explained above, and &lt;strong&gt;import the API to the Targeted WSO2 API Cloud Tenant&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
apimcli import-api &lt;span class="nt"&gt;-f&lt;/span&gt; ./path/SampleStore &lt;span class="nt"&gt;-e&lt;/span&gt; wso2apicloud &lt;span class="nt"&gt;--preserve-provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="nt"&gt;--update&lt;/span&gt; &lt;span class="nt"&gt;--verbose&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h6&gt;
  
  
  Go back to WSO2 API Cloud Web Platform and you can confirm that your thumbnail changes have been updated in web UI successfully like this.
&lt;/h6&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fttr8p81w65r0y2ndeoq3.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fttr8p81w65r0y2ndeoq3.PNG" alt="Alt Text" width="800" height="822"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;👉 What's Next?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=""&gt;Testing WSO2 API Cloud APIs using the CLI Tool&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Thank You&lt;/strong&gt;
&lt;/h3&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Hope you all enjoyed and learned something from this. Let me know your comments and suggestions in the discussion section.&lt;/em&gt;&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;👉 Visit me - &lt;a href="https://mihinduranasinghe.com/" rel="noopener noreferrer"&gt;https://mihinduranasinghe.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>wso2</category>
      <category>cloud</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>WSO2 API Cloud projects initialization and deployment using the CLI Tool</title>
      <dc:creator>Mihindu Ranasinghe</dc:creator>
      <pubDate>Sat, 23 Jan 2021 07:41:32 +0000</pubDate>
      <link>https://dev.to/mihinduranasinghe/wso2-api-cloud-projects-initialization-using-the-cli-tool-9oa</link>
      <guid>https://dev.to/mihinduranasinghe/wso2-api-cloud-projects-initialization-using-the-cli-tool-9oa</guid>
      <description>&lt;p&gt;&lt;strong&gt;WSO2 API Cloud delivers an enterprise-ready solution for creating, publishing, and managing all aspects of an API and its lifecycle. To register and get started with WSO2 API Cloud, go to&lt;/strong&gt; &lt;a href="http://wso2.com/cloud/api-cloud/" rel="noopener noreferrer"&gt;http://wso2.com/cloud/api-cloud/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can take a look at the &lt;a href="https://cloud.docs.wso2.com/en/latest/" rel="noopener noreferrer"&gt;WSO2 API Cloud Documentation&lt;/a&gt; to quickly try out designing , creating and publishing APIs &lt;strong&gt;from the Web UI&lt;/strong&gt;, subscribing to it &lt;strong&gt;from the Web UI&lt;/strong&gt; of the WSO2 API Cloud&lt;/p&gt;

&lt;h4&gt;
  
  
  In this article, we are focusing on Designing, Initializing and deploying APIs &lt;strong&gt;from the command line&lt;/strong&gt; using the &lt;strong&gt;APIMCLI tool&lt;/strong&gt;.
&lt;/h4&gt;

&lt;p&gt;👉 &lt;strong&gt;Pre-requisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt;Download API Controller based on your preferred platform (i.e., Mac, Windows, Linux).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.wso2.com/download/attachments/103334679/apimcli-2.0.13-macosx-x64.tar.gz" rel="noopener noreferrer"&gt;For MacOS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.wso2.com/download/attachments/103334679/apimcli-2.0.13-linux-i586.tar.gz" rel="noopener noreferrer"&gt;For Linux 32-bit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.wso2.com/download/attachments/103334679/apimcli-2.0.13-linux-x64.tar.gz" rel="noopener noreferrer"&gt;For Linux 64-bit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.wso2.com/download/attachments/103334679/apimcli-2.0.13-windows-i586.zip" rel="noopener noreferrer"&gt;For Windows 32-bit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.wso2.com/download/attachments/103334679/apimcli-2.0.13-windows-x64.zip" rel="noopener noreferrer"&gt;For Windows 64-bit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt;Extract the downloaded archive containing the CLI Tool to a preferred location and navigate to it from the terminal (using cd ).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt;Navigate to the working directory where the executable CLI Tool resides.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.&lt;/strong&gt;Execute the following command to start the CLI tool.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./apimcli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5.&lt;/strong&gt;Add the location of the extracted folder to your system's $PATH variable to be able to access the executable from anywhere.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apimcli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h4&gt;
  
  
  1. Adding the cloud gateway environment
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
apimcli add-env &lt;span class="nt"&gt;-n&lt;/span&gt; wso2apicloud &lt;span class="se"&gt;\&lt;/span&gt;
                      &lt;span class="nt"&gt;--registration&lt;/span&gt; https://gateway.api.cloud.wso2.com/client-registration/register &lt;span class="se"&gt;\&lt;/span&gt;
                      &lt;span class="nt"&gt;--apim&lt;/span&gt; https://gateway.api.cloud.wso2.com/pulisher &lt;span class="se"&gt;\&lt;/span&gt;
                      &lt;span class="nt"&gt;--token&lt;/span&gt; https://gateway.api.cloud.wso2.com/token &lt;span class="se"&gt;\&lt;/span&gt;
                      &lt;span class="nt"&gt;--import-export&lt;/span&gt; https://gateway.api.cloud.wso2.com/api-import-export &lt;span class="se"&gt;\&lt;/span&gt;
                      &lt;span class="nt"&gt;--admin&lt;/span&gt; https://gateway.api.cloud.wso2.com/api/am/admin/ &lt;span class="se"&gt;\&lt;/span&gt;
                      &lt;span class="nt"&gt;--api_list&lt;/span&gt; https://gateway.api.cloud.wso2.com/api/am/publisher/apis &lt;span class="se"&gt;\&lt;/span&gt;
                      &lt;span class="nt"&gt;--app_list&lt;/span&gt; https://gateway.api.cloud.wso2.com/api/am/store/applications


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h6&gt;
  
  
  Make sure the environment is configured by this command :
&lt;/h6&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apimcli list envs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  2. Create a new API project
&lt;/h4&gt;

&lt;p&gt;Usage: &lt;/p&gt;

&lt;p&gt;You can follow one of these example methods to initialize a project.                                                                                                                &lt;/p&gt;

&lt;p&gt;&lt;code&gt;apimcli init [project path] [flags]&lt;/code&gt;&lt;br&gt;
                                                                                                                                                                                                           Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Initialize with default swagger.yaml file and default API definition (You have to replace the generated API definition and Swagger with your actual values)&lt;/span&gt;
apimcli init SampleStore
&lt;span class="c"&gt;# Initialize with your actual swagger file path&lt;/span&gt;
apimcli init SampleStore &lt;span class="nt"&gt;--oas&lt;/span&gt; petstore.yaml
&lt;span class="c"&gt;# Initialize with your actual swagger file URL&lt;/span&gt;
apimcli init SampleStore &lt;span class="nt"&gt;--oas&lt;/span&gt; https://petstore.swagger.io/v2/swagger.json
&lt;span class="c"&gt;# Initialize with your actual swagger file and API Definition file&lt;/span&gt;
apimcli init SampleStore &lt;span class="nt"&gt;--oas&lt;/span&gt; ./swagger.yaml &lt;span class="nt"&gt;-d&lt;/span&gt; definition.yaml 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  A project folder with the following structure will be created in the given directory.
&lt;/h5&gt;

&lt;p&gt;├── api_params.yaml&lt;br&gt;
├── Docs&lt;br&gt;
│   └── FileContents&lt;br&gt;
├── Image&lt;br&gt;
├── Meta-information&lt;br&gt;
│   ├── api.yaml&lt;br&gt;
│   └── swagger.yaml&lt;br&gt;
├── README.md&lt;br&gt;
└── Sequences&lt;br&gt;
│    ├── fault-sequence&lt;br&gt;
│    ├── in-sequence&lt;br&gt;
│    └── out-sequence&lt;/p&gt;

&lt;p&gt;I have attached 2 sample files for &lt;strong&gt;api.yaml&lt;/strong&gt; and &lt;strong&gt;swagger.json&lt;/strong&gt; for your reference. &lt;/p&gt;

&lt;p&gt;You can get the hands-on experience by replacing below files with generated Meta-information in your directory and move forward with the article.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/mihinduranasinghe/6285853c3f186b107e9bddc4d550e16d" rel="noopener noreferrer"&gt;api.yaml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/mihinduranasinghe/0b083375f1fea5bcc03f7737804dc933" rel="noopener noreferrer"&gt;swagger.json&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to learn more on api.yaml configuration, here you can find out &lt;a href="https://gist.github.com/kasvith/01e704611b6c301f470ab0e3b5cb0607" rel="noopener noreferrer"&gt;gist&lt;/a&gt;&lt;/p&gt;



&lt;h4&gt;
  
  
  3. Deploying the API project to a targeted tenant in API Cloud
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;First of all you need to log into your targeted tenant in API Cloud by providing targeted tenant username &amp;amp; password .
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#apimcli login &amp;lt;Environment&amp;gt; -u &amp;lt;Username&amp;gt; -p &amp;lt;Password&amp;gt; &lt;/span&gt;
apimcli login wso2apicloud &lt;span class="nt"&gt;-u&lt;/span&gt; mihindu@wso2.com@development &lt;span class="nt"&gt;-p&lt;/span&gt; PASS54687 &lt;span class="nt"&gt;-k&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Also you can login like this :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8ve1hk5rf89b9o72tubg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8ve1hk5rf89b9o72tubg.png" alt="Alt Text" width="521" height="115"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After logging in to the targeted tenant, you can import the API using the following command.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
apimcli import-api &lt;span class="nt"&gt;-f&lt;/span&gt; ./path/SampleStore &lt;span class="nt"&gt;-e&lt;/span&gt; wso2apicloud &lt;span class="nt"&gt;--preserve-provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="nt"&gt;--update&lt;/span&gt; &lt;span class="nt"&gt;--verbose&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h5&gt;
  
  
  Make sure the API project is deployed successfully by this command :
&lt;/h5&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# apimcli list apis -e &amp;lt;environment&amp;gt; -k&lt;/span&gt;
apimcli list apis &lt;span class="nt"&gt;-e&lt;/span&gt; wso2apicloud &lt;span class="nt"&gt;-k&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h5&gt;
  
  
  Here the deployed APIs are listed:
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2hvorase7b82ym5qe8j4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2hvorase7b82ym5qe8j4.png" alt="Alt Text" width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h5&gt;
  
  
  You can log into the WSO2 API cloud portal and see the project is deployed successfully.
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6agzdd1b569mroryssh5.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6agzdd1b569mroryssh5.PNG" alt="Alt Text" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;How to export the API Project from the logged in tenant from the CLI&lt;/strong&gt; ?
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;# # apimcli export-api -n &amp;lt;API-name&amp;gt; -v &amp;lt;version&amp;gt; -r &amp;lt;provider&amp;gt; -e &amp;lt;environment&amp;gt; -u &amp;lt;username&amp;gt; -p &amp;lt;password&amp;gt; -k&lt;/span&gt;
&lt;span class="c"&gt;# # apimcli export-api --name &amp;lt;API-name&amp;gt; --version &amp;lt;version&amp;gt; --provider &amp;lt;provider&amp;gt; --environment &amp;lt;environment&amp;gt; --username &amp;lt;username&amp;gt; --password &amp;lt;password&amp;gt; --insecure&lt;/span&gt;
apimcli export-api &lt;span class="nt"&gt;-n&lt;/span&gt; SampleStore &lt;span class="nt"&gt;-v&lt;/span&gt; 1.0.0 &lt;span class="nt"&gt;-r&lt;/span&gt; mihindu@wso2.com@development &lt;span class="nt"&gt;-e&lt;/span&gt; wso2apicloud &lt;span class="nt"&gt;-k&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h5&gt;
  
  
  Once you exported successfully you will receive a response with the exported directory in your local machine.
&lt;/h5&gt;

&lt;p&gt;Response :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Successfully exported API!
Find the exported API at /Users/kim/.wso2apimcli/exported/apis/dev/SampleStore_1.0.0.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;DO YOU KNOW&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;How to update an API Cloud Project &lt;strong&gt;Thumbnail&lt;/strong&gt; from the &lt;strong&gt;CLI&lt;/strong&gt; ?&lt;/li&gt;
&lt;li&gt;How to add &lt;strong&gt;Mediation Sequences&lt;/strong&gt; for the API Cloud Project from the &lt;strong&gt;CLI&lt;/strong&gt; ?&lt;/li&gt;
&lt;li&gt;How to add &lt;strong&gt;API Scopes&lt;/strong&gt; from the &lt;strong&gt;CLI&lt;/strong&gt; ?&lt;/li&gt;
&lt;li&gt;How to add &lt;strong&gt;Documents&lt;/strong&gt; for the API Cloud Project from the &lt;strong&gt;CLI&lt;/strong&gt; ?&lt;/li&gt;
&lt;li&gt;How to &lt;strong&gt;invoke an API&lt;/strong&gt; in WSO2 API Cloud with a generated API Token, from the &lt;strong&gt;CLI&lt;/strong&gt; ?&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;👉 What's Next?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/mihinduranasinghe/wso2-api-cloud-adding-mediation-sequences-documents-and-api-thumbnails-from-cli-tool-3l5h"&gt;These sections will be covered in-detail in the next article.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Thank You&lt;/strong&gt;
&lt;/h3&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Hope you all enjoyed and learned something from this. Let me know your comments and suggestions in the discussion section.&lt;/em&gt;&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;👉 Visit me - &lt;a href="https://mihinduranasinghe.com/" rel="noopener noreferrer"&gt;https://mihinduranasinghe.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>cloud</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Using Docker Containers In Jobs - GitHub Actions</title>
      <dc:creator>Mihindu Ranasinghe</dc:creator>
      <pubDate>Fri, 04 Dec 2020 15:13:35 +0000</pubDate>
      <link>https://dev.to/mihinduranasinghe/using-docker-containers-in-jobs-github-actions-3eof</link>
      <guid>https://dev.to/mihinduranasinghe/using-docker-containers-in-jobs-github-actions-3eof</guid>
      <description>&lt;p&gt;👉 Prerequisites &lt;/p&gt;

&lt;p&gt;If you are new to GitHub Actions, I suggest you to read these articles&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/mihinduranasinghe/introduction-to-github-actions-part-1-1d6p"&gt;Introduction to Github Actions - GitHub Actions (Part 1)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/mihinduranasinghe/working-with-environment-variables-github-actions-part-2-46po"&gt;Working with environment variables - GitHub Actions(Part 2)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/mihinduranasinghe/working-with-external-actions-github-actions-part-3-3895"&gt;Working with external actions - GitHub Actions (Part 3)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;As we discussed in previous articles, we can run our workflows in virtual machines by using operating systems that GitHub Actions provides as GitHub Hosted Runners.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Using Docker Container&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We can use a docker container which will be installed on the the  virtual machine &amp;amp; then instead of running directly on virtual machine, our workflow will runs on a particular container.&lt;/p&gt;

&lt;p&gt; &lt;strong&gt;This can be an image from Docker Hub.&lt;/strong&gt; &lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Docker Hub&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Docker Hub is the platform which allows users to create, manage, and deliver their container applications. Docker Hub is the largest library of container images.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href="https://hub.docker.com/" rel="noopener noreferrer"&gt;Docker Hub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhnsyfj4zh1y5cg4phukr.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhnsyfj4zh1y5cg4phukr.PNG" alt="Alt Text" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you click on an image (For example Node), you can see all the dockerfile links with the respective tags.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwiior329v7okszi25woe.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwiior329v7okszi25woe.PNG" alt="Alt Text" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;How to use ?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You have to provide the, &lt;br&gt;
&lt;strong&gt;publisher-dockerhub-username : docker-image-tag&lt;/strong&gt; with the image tag under the "container:" &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can not use containers on windows and mac-os virtual machines.&lt;/li&gt;
&lt;li&gt;We can use containers only on ubuntu machines.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
name: workflow-name
on: push

jobs:
  job-name:
    runs-on: ubuntu-latest
    container:
      image: dockerhub-username:docker-image-tag

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;container&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;push&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;node-docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;node:14.15.0-alpine3.12&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also you can provide some other parameters like environment variables, ports &amp;amp; options...etc&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;container&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;push&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;node-docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;node:14.15.0-alpine3.12&lt;/span&gt;

     &lt;span class="c1"&gt;#env:&lt;/span&gt;
     &lt;span class="c1"&gt;#  ENV1: Available to this container only&lt;/span&gt;

     &lt;span class="c1"&gt;#ports: To expose our container&lt;/span&gt;

     &lt;span class="c1"&gt;#options: --cpus 1 --host&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So in next figure you can confirm that steps are running inside the container we initialized with dockerhub image, instead of running directly on the virtual machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;container&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;push&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;node-docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;node:14.15.0-alpine3.12&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Log the node version&lt;/span&gt;
           &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
             &lt;span class="s"&gt;node -v&lt;/span&gt;
             &lt;span class="s"&gt;cat /etc/os-release  &lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we echo the node version of the image and some operating system information of the docker container.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftnwy3fccih0i9gwtgeds.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftnwy3fccih0i9gwtgeds.PNG" alt="Alt Text" width="800" height="592"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  We can also specify multiple containers to run as services.
&lt;/h2&gt;

&lt;p&gt;If you have an application to run multiple services, you might need multiple images to run in our virtual machine. Normally we use &lt;strong&gt;Docker-Compose&lt;/strong&gt; to do something like that, **but in GitHub Actions we have a similar way to run this type of applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Running multiple docker containers in a job.&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Instead of having container here, we can provide "services: "&lt;br&gt;
We can give the services as docker-images under the "services:" and they run as separate containers in our virtual machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;workflow-name&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;push&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;job-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;service-name-1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dockerhub-username:docker-image-1&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
           &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;3001:3000&lt;/span&gt;

      &lt;span class="na"&gt;service-name-2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dockerhub-username:docker-image-2&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
           &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;4001:4000&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get from service-1&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://localhost:3001/api/users&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get from service-2&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://localhost:4001/api/items&lt;/span&gt;


      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;post a user example&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;curl&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-x&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;http://localhost:3001/api/user&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-H&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'Content-Type:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;application/json'&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-d&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;username"&lt;/span&gt;&lt;span class="na"&gt;\&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;\"hello"\, \"address"\&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sampleaddress"&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here it creates two containers for service-1 &amp;amp; service-2 inside our virtual machine&lt;/p&gt;

&lt;p&gt;In order to communicate between those two containers, we can use the service-name as the host name in the app.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Running docker containers in individual steps.&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In GitHub Actions, we can use different containers in different steps as well. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We can use "with:" key to provide inputs to this container in the particular step&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can give an &lt;strong&gt;entrypoint&lt;/strong&gt; in &lt;strong&gt;with:&lt;/strong&gt; key and override the entrypoint of the dockerfile&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To find some entrypoints of the echo, node ...etc use this commands&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ex 1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type -a  echo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Output - Entrypoint of echo in ubuntu:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo is  /bin/echo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ex 2 :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type -a  node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Output - Entrypoint of node in ubuntu:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node is  usr/local/bin/echo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use this "type -a " command in ubuntu to find some Entrypoints of the installed tools &amp;amp; softwares.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;container&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;push&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;node-docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;node:14.15.0-alpine3.12&lt;/span&gt;
      &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Log the parent container node version&lt;/span&gt;
           &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
             &lt;span class="s"&gt;node -v &lt;/span&gt;
           &lt;span class="c1"&gt;# Echo the node version of the parent container&lt;/span&gt;


         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Log the step container node version&lt;/span&gt;
           &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker://node:12.14.1-alpine3.10&lt;/span&gt;
           &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;usr/local/bin/echo&lt;/span&gt;
             &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;-v&lt;/span&gt;
            &lt;span class="c1"&gt;# Echo the node version of this step container based on this 12.14.1-alpine3.10 image&lt;/span&gt;


         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Step with docker to echo a string&lt;/span&gt;
           &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker://node:12.14.1-alpine3.10&lt;/span&gt;
           &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/bin/echo&lt;/span&gt;
             &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Hello Docker !&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Push the workflow file into the repository &amp;amp; check the &lt;strong&gt;Actions&lt;/strong&gt; window of the repository&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Outputs:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;v14.15.0
v12.14.1
Hello Docker !

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 What's Next?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=""&gt;Trigger workflows manually using the repository dispatch event&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Thank You&lt;/strong&gt;
&lt;/h2&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Hope you all enjoyed and learned something from this. Let me know your comments and suggestions in the discussion section.&lt;/em&gt;&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;👉 Visit me - &lt;a href="https://mihinduranasinghe.com/" rel="noopener noreferrer"&gt;https://mihinduranasinghe.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>docker</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Working with external actions - GitHub Actions (Part 3)</title>
      <dc:creator>Mihindu Ranasinghe</dc:creator>
      <pubDate>Tue, 01 Dec 2020 20:06:34 +0000</pubDate>
      <link>https://dev.to/mihinduranasinghe/working-with-external-actions-github-actions-part-3-3895</link>
      <guid>https://dev.to/mihinduranasinghe/working-with-external-actions-github-actions-part-3-3895</guid>
      <description>&lt;p&gt;👉 Prerequisites &lt;/p&gt;

&lt;p&gt;If you are new to GitHub Actions, I suggest you to read these articles&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/mihinduranasinghe/introduction-to-github-actions-part-1-1d6p"&gt;Introduction to Github Actions - GitHub Actions (Part 1)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/mihinduranasinghe/working-with-environment-variables-github-actions-part-2-46po"&gt;Working with environment variables - GitHub Actions(Part 2)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Here is the cool thing about GitHub actions.
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Instead of automating each and every step by your own from the scratch , you can use reusable codes in Github Actions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mainly there are two types of reusable actions. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We can create private reusable actions and use them inside our local workflows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can use public reusable actions from the marketplace&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In this article,&lt;/strong&gt; let's have a look at how we can use publicly available external actions from the &lt;em&gt;marketplace&lt;/em&gt; and how we can use them inside our workflow.&lt;/p&gt;

&lt;h4&gt;
  
  
  GitHub Actions Marketplace
&lt;/h4&gt;

&lt;p&gt;GitHub Actions Marketplace is where you can find out reusable codes/workflows also known as "actions" implemented by someone in the GitHub Actions community.&lt;/p&gt;

&lt;p&gt;Most of the reputed cloud companies like AWS, Google, Azure have published their own public actions for their clients.&lt;/p&gt;

&lt;p&gt;Not only companies, also the individuals in the Github Actions Community have build up and published some useful actions in the Marketplace&lt;/p&gt;

&lt;p&gt;Link : &lt;a href="https://github.com/marketplace?type=actions" rel="noopener noreferrer"&gt;Marketplace&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0wg9fy113zoqvt712nbi.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0wg9fy113zoqvt712nbi.JPG" alt="Alt Text" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You can search for actions in the search bar of the Marketplace.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once you click on an action, you will be redirected to a readme(documentation) page and there you can find a brief about the action and how we can use it in our workflow and what is the &lt;strong&gt;reference(signature)&lt;/strong&gt; of the particular workflow and what are the &lt;strong&gt;inputs&lt;/strong&gt; we have to give when we use the action in our workflow. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to reference a public action ?
&lt;/h2&gt;

&lt;p&gt;There are several ways that we can reference a public action from the marketplace.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Referencing a branch&lt;/li&gt;
&lt;li&gt;Referencing a version&lt;/li&gt;
&lt;li&gt;Referencing a commit&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is the basic structure of a step to use a public action :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Any-relevant-name-for-the-step&lt;/span&gt;
   &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;step-1-id(Optional)&lt;/span&gt;
   &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;#reference&lt;/span&gt;
   &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;#inputs&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have to provide a reference with the "uses:" tag and we can provide relevant inputs under "with:" tag.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;u&gt;Referencing a branch:&lt;/u&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;publisher-username/repo-name@branch-name&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;u&gt;Referencing a version:&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Find the releases from the marketplace for the particular action&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;publisher-username/repo-name@v1.1.0&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;u&gt;Referencing a commit ID :&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Explore the commit history of the action and find a specific commit ID&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;publisher-username/repo-name@commit-ID&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Note :
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If you reference a branch, actually &lt;strong&gt;it is not really preferred&lt;/strong&gt;. Some breaking changes might occur when the publisher changes the code in the particular branch you referred.  Then your workflow might fail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you reference a specific Version, It will help to mitigate this problem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The safest way&lt;/strong&gt; is to have a stable workflow is to use specific &lt;strong&gt;commit ID&lt;/strong&gt; to reference an action.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  An easier way to find the reference of an action
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to the action page in the marketplace.&lt;/li&gt;
&lt;li&gt;Click on this green color box or drop down and find the specific version.&lt;/li&gt;
&lt;li&gt;copy paste the reference. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Feojo0al0mypw94pl1zas.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Feojo0al0mypw94pl1zas.JPG" alt="Alt Text" width="800" height="603"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h4&gt;
  
  
  For example lets use this &lt;a href="https://github.com/actions/hello-world-javascript-action" rel="noopener noreferrer"&gt;Hello world javascript action&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;If you have read the documentation, there are few inputs you can provide.&lt;/p&gt;

&lt;p&gt;I provide here the "who-to-greet" input with a sample name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;name-of-the-workflow&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;sample-job-1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;step-1&lt;/span&gt;
              &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/hello-world-javascript-action@v1.1&lt;/span&gt;
              &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                 &lt;span class="na"&gt;who-to-greet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Mihindu&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello Mihindu!

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  Another useful action for any workflow.
&lt;/h4&gt;

&lt;p&gt;Before working with the repo files from the workflow steps, we need to clone our repo files into the virtual machine that we created in the job. &lt;/p&gt;

&lt;p&gt;So this is something we do at very first of many workflows. So that you can use this &lt;a href="https://github.com/marketplace/actions/checkout" rel="noopener noreferrer"&gt;checkout&lt;/a&gt; public action and clone repo files into VM very easily.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;name-of-the-workflow&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;sample-job-1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Clone-repo-files-into-vm&lt;/span&gt;
              &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2.3.4&lt;/span&gt;

            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ls&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are many more useful actions in the marketplace. Take your time and refer them and use them in your workflows according to the purpose.&lt;/p&gt;

&lt;p&gt;👉 What's Next?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/mihinduranasinghe/using-docker-containers-in-jobs-github-actions-3eof"&gt;Using Docker Containers In Jobs - GitHub Actions (Part 4)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Thank You&lt;/strong&gt;
&lt;/h2&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Hope you all enjoyed and learned something from this. Let me know your comments and suggestions in the discussion section&lt;/em&gt;&lt;/strong&gt;.
&lt;/h5&gt;

&lt;p&gt;👉 Visit me - &lt;a href="https://mihinduranasinghe.com/" rel="noopener noreferrer"&gt;https://mihinduranasinghe.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Working with environment variables - GitHub Actions (Part 2)</title>
      <dc:creator>Mihindu Ranasinghe</dc:creator>
      <pubDate>Mon, 30 Nov 2020 16:07:15 +0000</pubDate>
      <link>https://dev.to/mihinduranasinghe/working-with-environment-variables-github-actions-part-2-46po</link>
      <guid>https://dev.to/mihinduranasinghe/working-with-environment-variables-github-actions-part-2-46po</guid>
      <description>&lt;p&gt;👉 Prerequisites &lt;/p&gt;

&lt;p&gt;If you are new to GitHub Actions, I suggest you to read my &lt;a href="https://dev.to/mihinduranasinghe/introduction-to-github-actions-part-1-1d6p"&gt;Introduction to Github Actions - GitHub Actions (Part 1)&lt;/a&gt; article.&lt;/p&gt;

&lt;h2&gt;
  
  
  There are mainly three types of environment variables in GitHub Actions.
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Custom Environment Variables .&lt;/li&gt;
&lt;li&gt;Default Environment Variables.&lt;/li&gt;
&lt;li&gt;Encrypted Environment Variables.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Custom Environment Variables&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Custom environment variables can be declared by ourselves inside any workflow file. &lt;/p&gt;

&lt;p&gt;We can declare custom environment variables under different access scope in a workflow file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Workflow level&lt;/li&gt;
&lt;li&gt;Job level &lt;/li&gt;
&lt;li&gt;Steps level&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So then the declared variable can be accessed by the particular scope only.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Workflow level custom environment variables&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here I have declared a variable called PUBLICENV in workflow level and trying to echo it in different levels.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;workflow-level-custom-environment-variables&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# Here the environment variable is declared in workflow level&lt;/span&gt;
&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;PUBLICENV&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Available for all jobs in this workflow&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;sample-job-1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;step-1&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "${PUBLICENV}"&lt;/span&gt;
              &lt;span class="c1"&gt;# This will echo the value/string of PUBLICENV&lt;/span&gt;

            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;step-2&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "${PUBLICENV}"&lt;/span&gt;
              &lt;span class="c1"&gt;# This will echo the value/string of PUBLICENV&lt;/span&gt;

    &lt;span class="na"&gt;sample-job-2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "${PUBLICENV}"&lt;/span&gt;
            &lt;span class="c1"&gt;# This will echo the value/string of PUBLICENV&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Job level custom environment variables&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here I have declared a variable called JOBENV in "sample-job-1" level and trying to echo it in different levels.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;job-level-custom-environment-variables&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;sample-job-1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;JOBENV&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Available for this specific job only&lt;/span&gt;
            &lt;span class="c1"&gt;# Here the environment variable is declared in job level&lt;/span&gt;
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;step-1&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "${JOBENV}"&lt;/span&gt;
              &lt;span class="c1"&gt;# This will echo the value/string of JOBENV&lt;/span&gt;

            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;step-2&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "${JOBENV}"&lt;/span&gt;
              &lt;span class="c1"&gt;# This will echo the value/string of JOBENV&lt;/span&gt;

    &lt;span class="na"&gt;sample-job-2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "${JOBENV}"&lt;/span&gt;
            &lt;span class="c1"&gt;# This will NOT echo the value/string of JOBENV&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Step level custom environment variables&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here I have declared a variable called STEPENV in "step-1" level inside the "sample-job-1" and trying to echo it in different levels.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;step-level-custom-environment-variables&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;sample-job-1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;step-1&lt;/span&gt;
              &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;STEPENV&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Available for this specific job only&lt;/span&gt;
                  &lt;span class="c1"&gt;# Here the environment variable is declared in step level&lt;/span&gt;

              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "${STEPENV}"&lt;/span&gt;
              &lt;span class="c1"&gt;# This will echo the value/string of STEPENV&lt;/span&gt;

            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;step-2&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "${STEPENV}"&lt;/span&gt;
              &lt;span class="c1"&gt;# This will NOT echo the value/string of STEPENV&lt;/span&gt;

    &lt;span class="na"&gt;sample-job-2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "${STEPENV}"&lt;/span&gt;
            &lt;span class="c1"&gt;# This will NOT echo the value/string of STEPENV&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;2. Default Environment Variables&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;GitHub provides some default environment variables for many useful parameters of your repository. We can use them anywhere inside the workflow.&lt;/p&gt;

&lt;h4&gt;
  
  
  Here is a list of default env variables in GitHub Actions
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GITHUB_WORKFLOW&lt;/strong&gt; The name of the workflow.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GITHUB_RUN_ID&lt;/strong&gt; A unique number for each run within a repository. This number does not change if you re-run the workflow run.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GITHUB_RUN_NUMBER&lt;/strong&gt; A unique number for each run of a particular workflow in a repository. This number begins at 1 for the workflow's first run, and increments with each new run. This number does not change if you re-run the workflow run.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GITHUB_ACTION&lt;/strong&gt; The unique identifier (id) of the action.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GITHUB_ACTIONS&lt;/strong&gt;    Always set to true when GitHub Actions is running the workflow. You can use this variable to differentiate when tests are being run locally or by GitHub Actions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GITHUB_ACTOR&lt;/strong&gt;  The name of the person or app that initiated the workflow.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GITHUB_REPOSITORY&lt;/strong&gt; The owner and repository name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GITHUB_EVENT_NAME&lt;/strong&gt; The name of the webhook event that triggered the workflow.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GITHUB_EVENT_PATH&lt;/strong&gt; The path of the file with the complete webhook event payload. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GITHUB_WORKSPACE&lt;/strong&gt;  The GitHub workspace directory path. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GITHUB_SHA&lt;/strong&gt;    The commit SHA that triggered the workflow. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GITHUB_REF&lt;/strong&gt;    The branch or tag ref that triggered the workflow.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GITHUB_HEAD_REF&lt;/strong&gt;   Only set for forked repositories. The branch of the head repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GITHUB_BASE_REF&lt;/strong&gt;   Only set for forked repositories. The branch of the base repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GITHUB_SERVER_URL&lt;/strong&gt; Returns the URL of the GitHub server. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GITHUB_API_URL&lt;/strong&gt;    Returns the API URL. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GITHUB_GRAPHQL_URL&lt;/strong&gt;    Returns the GraphQL API URL.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default-environment-variables&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;sample-job&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo-default-env-variables&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
                  &lt;span class="s"&gt;echo "Home: ${HOME}"&lt;/span&gt;
                  &lt;span class="s"&gt;echo "GITHUB_WORKFLOW: ${GITHUB_WORKFLOW}"&lt;/span&gt;
                  &lt;span class="s"&gt;echo "GITHUB_ACTIONS: ${GITHUB_ACTIONS}"&lt;/span&gt;
                  &lt;span class="s"&gt;echo "GITHUB_ACTOR: ${GITHUB_ACTOR}"&lt;/span&gt;
                  &lt;span class="s"&gt;echo "GITHUB_REPOSITORY: ${GITHUB_REPOSITORY}"&lt;/span&gt;
                  &lt;span class="s"&gt;echo "GITHUB_EVENT_NAME: ${GITHUB_EVENT_NAME}"&lt;/span&gt;
                  &lt;span class="s"&gt;echo "GITHUB_WORKSPACE: ${GITHUB_WORKSPACE}"&lt;/span&gt;
                  &lt;span class="s"&gt;echo "GITHUB_SHA: ${GITHUB_SHA}"&lt;/span&gt;
                  &lt;span class="s"&gt;echo "GITHUB_REF: ${GITHUB_REF}"&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Outputs:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fakospckj1wyqlbvwk434.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fakospckj1wyqlbvwk434.png" alt="Alt Text" width="551" height="142"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;3. Encrypted Environment Variables&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In GitHub Actions, we can create encrypted environment variables as well. We can use &lt;strong&gt;GitHub Secrets&lt;/strong&gt; to store API keys and passwords kind of things.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on the settings in the repository&lt;/li&gt;
&lt;li&gt;Click on the secrets&lt;/li&gt;
&lt;li&gt;Click on the "New Repository Secret"&lt;/li&gt;
&lt;li&gt;Give YOUR_SECRET_NAME and the VALUE and click on the "Add Secret"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn45by6hur4tktp8gpujl.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn45by6hur4tktp8gpujl.JPG" alt="Alt Text" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvjt2cgwcx4p48i67jidd.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvjt2cgwcx4p48i67jidd.JPG" alt="Alt Text" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4mbxbc48mvf31e3sqmk3.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4mbxbc48mvf31e3sqmk3.JPG" alt="Alt Text" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is an example code how we can re use encrypted variables without exposing the value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;working-with-encrypted-environment-variables&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;develop&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;sample-job&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy-to-staging&lt;/span&gt;
              &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.event_name == 'push' &amp;amp;&amp;amp; github.ref == 'refs/heads/develop'&lt;/span&gt;
              &lt;span class="c1"&gt;# Here this will be triggered only when the "push" event is performed only to the specific "develop" branch&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx surge --project ./build --domain eight-circle.surge.sh&lt;/span&gt;
              &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;SURGE_LOGIN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{secrets.SURGE_LOGIN}}&lt;/span&gt;
                  &lt;span class="na"&gt;SURGE_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{secrets.SURGE_TOKEN}}&lt;/span&gt;
                  &lt;span class="c1"&gt;# SURGE_LOGIN &amp;amp; SURGE_TOKEN is stored as github secrets&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  👏 Bonus Tip :
&lt;/h3&gt;

&lt;p&gt;In the Actions log screen, when any step is passed, it indicates a green check mark and when a step is failed, it indicates a red check mark but we can not see the exact error there unless enabling debugging.&lt;/p&gt;

&lt;p&gt;To enable debugging in GitHub Actions, store these two encrypted environment variables in github secrets in the perticular repository. Then when a step is failed, you will see debug messages in the same log screen &amp;amp; it makes you easier to debug your errors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Secret : ACTIONS_STEP_DEBUG 
Value  : TRUE

Secret : ACTIONS_RUNNER_DEBUG
Value  : TRUE

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 What's Next?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/mihinduranasinghe/working-with-external-actions-github-actions-part-3-3895"&gt;Working with external actions - GitHub Actions (Part 3)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Thank You&lt;/strong&gt;
&lt;/h2&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Hope you all enjoyed and learned something from this. Let me know your comments and suggestions in the discussion section&lt;/em&gt;&lt;/strong&gt;.
&lt;/h5&gt;

&lt;p&gt;👉 Visit me - &lt;a href="https://mihinduranasinghe.com/" rel="noopener noreferrer"&gt;https://mihinduranasinghe.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>devops</category>
      <category>cloud</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Introduction to GitHub Actions ( Part 1 )</title>
      <dc:creator>Mihindu Ranasinghe</dc:creator>
      <pubDate>Sun, 29 Nov 2020 13:36:26 +0000</pubDate>
      <link>https://dev.to/mihinduranasinghe/introduction-to-github-actions-part-1-1d6p</link>
      <guid>https://dev.to/mihinduranasinghe/introduction-to-github-actions-part-1-1d6p</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;What is GitHub Actions ?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;GitHub Actions makes it really easy to automate all your software workflows with &lt;strong&gt;automating CICD pipelines, Building, Testing and Deploying&lt;/strong&gt; your code directly from your GitHub repository even without any third party integrations like Jenkins. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6ybie4of6ulw84z33a9c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6ybie4of6ulw84z33a9c.png" alt="Alt Text" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can automate &lt;strong&gt;code reviews, branch management and issues&lt;/strong&gt; and we can trigger any workflow with the GitHub events.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;GitHub Actions Overview&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here you can see and understand the big picture of GitHub Actions workflow. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8tk4tgjbqdiqtk5bxeww.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8tk4tgjbqdiqtk5bxeww.JPG" alt="Alt Text" width="800" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  GitHub Events
&lt;/h4&gt;

&lt;p&gt;I hope you have a basic idea about what GitHub events are. If you are familiar with Git &amp;amp; GitHub you should have worked with GitHub events.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pushing a code into a repository branch &lt;/li&gt;
&lt;li&gt;Opening &amp;amp; closing a pull request&lt;/li&gt;
&lt;li&gt;Code reviewing &lt;/li&gt;
&lt;li&gt;Merging&lt;/li&gt;
&lt;li&gt;Opening and closing Issues&lt;/li&gt;
&lt;li&gt;Assigning issues&lt;/li&gt;
&lt;li&gt;Re-opening issues 
like that,
We can trigger any automated workflow when a GitHub event is performed. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So actually this is the beauty of GitHub Actions. &lt;/p&gt;

&lt;h4&gt;
  
  
  GitHub Server
&lt;/h4&gt;

&lt;p&gt;GitHub actions are triggered inside a GitHub server. We can create multiple workflows &amp;amp; multiple jobs in GitHub actions. As you see on the above figure, each and every Job we create and script, is running on a separate virtual machine inside the GitHub server. &lt;/p&gt;

&lt;p&gt;We can automate actions as steps inside each and every job such as step1 step2 step3...&lt;/p&gt;

&lt;p&gt;Virtual machines in GitHub server which are also known as &lt;strong&gt;Runners.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;VMs (Runners)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A runner is also known as any virtual machine with the GitHub Actions Runner Application is installed. Because GitHub Actions Runner is the core application part of GitHub actions which allows to run/trigger any workflow in this platform.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjw8kcalcpucsqxi5ekvg.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjw8kcalcpucsqxi5ekvg.JPG" alt="Alt Text" width="800" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Mainly there are two types of runners as you see on this figure such as&lt;/em&gt; &lt;strong&gt;&lt;em&gt;GitHub hosted runners&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;and&lt;/em&gt; &lt;strong&gt;&lt;em&gt;Self Hosted runners.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  👏GitHub Hosted Runners
&lt;/h4&gt;

&lt;p&gt;GitHub Hosted runners are some virtual machines that github team provides us to use directly. &lt;/p&gt;

&lt;p&gt;For example, Linux. Windows, Mac OS virtual machines are there with &lt;em&gt;pre-installed software like GIT, CURL, NPM, YARN, PIP, NODE.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;These GitHub hosted machines are , &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Easy to use&lt;/em&gt; &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;We can not customize&lt;/em&gt; it as we want.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Fully maintained by the GitHub team.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  👏Self Hosted Runners
&lt;/h4&gt;

&lt;p&gt;Self hosted runners are the machines that we can manage and maintain as we want. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;You have full control over the hardware, software, operating system of the vm and also the tools which need to be configured to automate some commands.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Most of the cloud companies like AWS Azzure GCP have developed their CICD automation action setups and published in GitHub Actions Marketplace for their clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Triggering Point&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Mainly In GitHub actions we have to work with YAML files. If you are not familiar with YAML format and YAML files please feel free to read &lt;a href="https://dev.to/mihinduranasinghe/github-actions-part-1-1192-temp-slug-8698647/"&gt;this&lt;/a&gt; article about YAML.&lt;/p&gt;

&lt;p&gt;First of all we need to have a repository and that should be in public.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Specially note that private repositories cannot be used with GitHub actions in the &lt;strong&gt;free version of GitHub.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When it comes to the triggering point,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpqx3b9np6mxoobsq9fqa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpqx3b9np6mxoobsq9fqa.png" alt="Alt Text" width="440" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have to create a folder called “.github‘ in the root of the repository and we have  to create a folder called  “workflows”, inside the “.github” folder. We have to create our own YAML file inside the “workflows” folder.&lt;/p&gt;

&lt;p&gt;Here is the standard triggering point of GitHub actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Workflow Overview&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here you can see a sample screenshot of triggering a workflow. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F03d8va5q4dbbdhdlztkl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F03d8va5q4dbbdhdlztkl.png" alt="Alt Text" width="671" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Actions window is where we can monitor our workflows. &lt;/li&gt;
&lt;li&gt;Here you can see the workflow name, and jobs on the left side of this window. &lt;/li&gt;
&lt;li&gt;GitHub actions logs every step in the automation very clearly&lt;/li&gt;
&lt;li&gt;When a step is passed, it indicates a green check mark or when a step is failed it indicates a red check mark as well.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also we can debug those errors as well in this log screen when a step is failed.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Basic structure of a GitHub Actions Workflow&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;First of all create a github repository and initialize it and create a yml file in the triggering point of the repository. &lt;strong&gt;(.github &amp;gt; workflows &amp;gt; sample.yml)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👏👏 Here is the basic structure...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Any-Name&lt;/span&gt; &lt;span class="c1"&gt;#Name of the workflow&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# On which events this workflow should be triggered. We can use this as an array as well&lt;/span&gt;

&lt;span class="c1"&gt;# on: [push, pull_request, issue]&lt;/span&gt;

&lt;span class="c1"&gt;# We can specify events like this as well&lt;/span&gt;
&lt;span class="c1"&gt;# on:&lt;/span&gt;
&lt;span class="c1"&gt;#   pull_request:&lt;/span&gt;
&lt;span class="c1"&gt;#     types: [opened, closed, reopened]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;run-shell-command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;         &lt;span class="c1"&gt;# Name of the job 1&lt;/span&gt;
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt; &lt;span class="c1"&gt;# Selecting a GitHub Hosted Runner (Here selected an ubuntu machine)&lt;/span&gt;

        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;                      &lt;span class="c1"&gt;# Automated Steps of the job&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo a string&lt;/span&gt;   &lt;span class="c1"&gt;# Name of the Step 1 (Optional)&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "Hello"&lt;/span&gt;     &lt;span class="c1"&gt;# command of the step 1&lt;/span&gt;

            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;multiline commands&lt;/span&gt;  &lt;span class="c1"&gt;# Name of the Step 2 &lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;                    &lt;span class="c1"&gt;# Multiline commands of the step 2&lt;/span&gt;
                  &lt;span class="s"&gt;node -v&lt;/span&gt;
                  &lt;span class="s"&gt;npm -v&lt;/span&gt;

            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cloning repo files into the vm&lt;/span&gt;   &lt;span class="c1"&gt;# Consuming pre published actions from the marketplace&lt;/span&gt;
              &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2.3.4&lt;/span&gt;          &lt;span class="c1"&gt;# Signature of the action you want to use here from the market place&lt;/span&gt;

    &lt;span class="na"&gt;run-windows-command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;              &lt;span class="c1"&gt;# Name of the job 2&lt;/span&gt;
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;windows-latest&lt;/span&gt;       &lt;span class="c1"&gt;# Selecting a GitHub Hosted Runner (Here selected a windows machine)&lt;/span&gt;
        &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;run-shell-command"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# If we want to run the first job before triggering the this job, we can set 'needs'&lt;/span&gt;
        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Echo the Directory&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pwd&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Please note that, keeping indents is a must when it comes to github actions workflows.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;you can set many types of events to trigger the workflow in "on:" section as follows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Events which can trigger a worfkflow &lt;a href="https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We can specify individual steps to be triggered for specific events as well with if conditions. (It will be explained in a separate article)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Once the scripting is done, you can push this into the remote repository and see how the workflow is triggering in "actions" window of the github repository.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consuming public actions from the marketplace, an in-detail article will be available soon.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉What's Next?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/mihinduranasinghe/working-with-environment-variables-github-actions-part-2-46po"&gt;Working with environment variables - GitHub Actions(Part 2)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Thank You&lt;/strong&gt;
&lt;/h2&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Hope you all enjoyed and learned something from this. Let me know your comments and suggestions in the discussion section&lt;/em&gt;&lt;/strong&gt;.
&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;NOTE :&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This article is for giving you a start to GitHub Actions and giving a brief introduction regarding what GitHub Actions is and what we can do with GitHub Actions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I will be writing few articles with some hands-on demonstrations how we can use GitHub Actions in real world.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Visit me - &lt;a href="https://mihinduranasinghe.com/" rel="noopener noreferrer"&gt;https://mihinduranasinghe.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>devops</category>
      <category>cloud</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Software Licensing</title>
      <dc:creator>Mihindu Ranasinghe</dc:creator>
      <pubDate>Tue, 08 Sep 2020 03:44:59 +0000</pubDate>
      <link>https://dev.to/mihinduranasinghe/software-licensing-15bo</link>
      <guid>https://dev.to/mihinduranasinghe/software-licensing-15bo</guid>
      <description>&lt;p&gt;A software license is a document that provides legally binding guidelines for the use and distribution of software.&lt;br&gt;
Software licenses typically provide end users with the right to one or more copies of the software without violating copyrights. The license also defines the responsibilities of the parties entering into the license agreement and may impose restrictions on how the software can be used. Software licensing terms and conditions usually include fair use of the software, the limitations of liability, warranties and disclaimers and protections if the software or its use infringes on the intellectual property rights of others. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2ixszpkafcty7z78dwws.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2ixszpkafcty7z78dwws.jpeg" alt="Alt Text" width="300" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Why Software Licensing Is Important
&lt;/h1&gt;

&lt;p&gt;Businesses must be savvy in the licenses they purchase to ensure firstly they are using software legally and secondly, they aren't paying for licenses that aren't being used. By acquiring too many software licenses you're wasting company resources, without enough you leave yourself liable to a potential lawsuit (which is quite costly). Finding the right license agreement can also make it easier to manage software in your company.&lt;/p&gt;

&lt;h1&gt;
  
  
  Ownership vs. licensing
&lt;/h1&gt;

&lt;p&gt;Many proprietary or open source software houses sell the SW copy with a license to use it. There isn't any transferring of ownership of the good to the user, which hasn't the warranty of a for life availability of the software, nor isn't entitled to sell, rent, give it to someone, copy or redistribute it on the Web. &lt;/p&gt;

&lt;p&gt;License terms and conditions may specify further legal clauses that users can't negotiate individually or by way of a consumer organization, and can uniquely accept or refuse, returning the product back to the vendor. This right can be effectively applied where the jurisdiction provides a mandatory time for the good decline right after the purchase (as in the European Union law), or a mandatory public advertisement of the license terms, so as to be made readable by users before their purchasing.&lt;/p&gt;

&lt;p&gt;In the United States, Section 117 of the Copyright Act gives the owner of a particular copy of software the explicit right to use the software with a computer, even if use of the software with a computer requires the making of incidental copies or adaptations (acts which could otherwise potentially constitute copyright infringement). Therefore, the owner of a copy of computer software is legally entitled to use that copy of software. Hence, if the end-user of software is the owner of the respective copy, then the end-user may legally use the software without a license from the software publisher.&lt;/p&gt;

&lt;p&gt;The ownership of digital goods, like software applications and video games, is challenged by "licensed, not sold" EULAs of digital distributors like Steam. In the European Union, the European Court of Justice held that a copyright holder cannot oppose the resale of a digitally sold software, in accordance with the rule of copyright exhaustion on first sale as ownership is transferred, and questions therefore the "licensed, not sold" EULA. The Swiss-based company UsedSoft innovated the resale of business software and fought for this right in court. In Europe, EU Directive 2009/24/EC expressly permits trading used computer programs &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fon7sg9cczrqvrpf40x6x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fon7sg9cczrqvrpf40x6x.png" alt="Alt Text" width="318" height="159"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Methods for Licensing Software
&lt;/h1&gt;

&lt;p&gt;An end-user license agreement (EULA) is one approach vendors can take to license their software. This is a contract between the licensor and purchaser, establishing the purchaser's right to use the software. The contract may include the different ways the software can be used as well as any rights the buyer has obtained by purchasing the software. This is one of the more basic and commonly used ways to license software.&lt;/p&gt;

&lt;p&gt;If you're using SaaS and as a result your applications are cloud based, the software license is usually subscription based. That is, you will pay for each user on a monthly (or some other period) basis. This type of software license offers greater flexibility. It is also beneficial in that you only pay for what you need " allowing you to scale your business without repercussions.&lt;/p&gt;

&lt;p&gt;There's also the question of whether you can re-sell your software license if you're no longer using it. There is no black and white answer to this question. The answer can generally be found in the EULA. From a legal standpoint there may be question marks over the enforceability of EULA's given to users after they purchased the software given they weren't aware of these conditions at the time the contract was formed. However I will not go into depth about questions of law.&lt;/p&gt;

&lt;p&gt;Another method of licensing software is by white labelling it. This is where a product is created by one company and then re-branded by another company. As a result, the software/product belongs to the company that created it. There is a software license in place which permits the company benefiting from the white label to use the software.&lt;/p&gt;

&lt;h1&gt;
  
  
  Different types of software licenses require you to meet certain obligations if you want to reuse the code.
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Here are 5 common types of software licenses.
&lt;/h3&gt;

&lt;p&gt;If you write code, you also reuse code, including code snippets, libraries, functions, frameworks, and entire applications. All software code comes with certain rights and obligations if you want to add it to your codebase. Free and open source software (FOSS) is free of cost, but you aren’t free to use it as you wish. Even unlicensed code snippets copied from Stack Overflow have obligations for reuse. But formally developed code usually comes with a specific software license.&lt;/p&gt;

&lt;p&gt;There are many different types of software licenses, and the penalties for license noncompliance can be harsh. If you reuse a component without following the obligations of its license, the licensor might sue, and you might be forced to publish your own source code. To protect your code and your organization, you need to understand these software licenses before using any code, including libraries and frameworks, you didn’t write yourself. See our list of the top open source licenses and their potential legal risks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Public domain.
&lt;/h3&gt;

&lt;p&gt;This is the most permissive type of software license. When software is in the public domain, anyone can modify and use the software without any restrictions. But you should always make sure it’s secure before adding it to your own codebase. &lt;/p&gt;

&lt;h4&gt;
  
  
  Warning:
&lt;/h4&gt;

&lt;p&gt;Code that doesn’t have an explicit license is NOT automatically in the public domain. This includes code snippets you find on the internet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Permissive.
&lt;/h3&gt;

&lt;p&gt;Permissive licenses are also known as “Apache style” or “BSD style.” They contain minimal requirements about how the software can be modified or redistributed. This type of software license is perhaps the most popular license used with free and open source software. Aside from the Apache License and the BSD License, another common variant is the MIT License.&lt;/p&gt;

&lt;h3&gt;
  
  
  LGPL.
&lt;/h3&gt;

&lt;p&gt;The GNU Lesser General Public License allows you to link to open source libraries in your software. If you simply compile or link an LGPL-licensed library with your own code, you can release your application under any license you want, even a proprietary license. But if you modify the library or copy parts of it into your code, you’ll have to release your application under similar terms as the LGPL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Copyleft.
&lt;/h3&gt;

&lt;p&gt;Copyleft licenses are also known as reciprocal licenses or restrictive licenses. The most well-known example of a copyleft or reciprocal license is the GPL. These licenses allow you to modify the licensed code and distribute new works based on it, as long as you distribute any new works or adaptations under the same software license. &lt;br&gt;
For example, a component’s license might say the work is free to use and distribute for personal use only. So any derivative you create would also be limited to personal use only. (A derivative is any new software you develop that contains the component.)&lt;/p&gt;

&lt;p&gt;The catch here is that the users of your software would also have the right to modify the code. Therefore, you’d have to make your own source code available. But of course, exposing your source code may not be in your best interests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Proprietary.
&lt;/h3&gt;

&lt;p&gt;This is the most restrictive. The idea behind it is that all rights are reserved. It’s generally used for proprietary software where the work may not be modified or redistributed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flrgxvo5bfj6ndtlstq69.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flrgxvo5bfj6ndtlstq69.jpg" alt="Alt Text" width="600" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  How Does Licensing Work On The WorkingMouse Platform
&lt;/h1&gt;

&lt;p&gt;The License Agreement between WorkingMouse and our customers gives them access to use the platform for developing and maintaining their software application(s). It allows customers to issue support tickets to WorkingMouse for assistance with server administration, bug fixing and minor enhancements. The license ensures WorkingMouse can support customers as they embark on their journey. &lt;/p&gt;

&lt;p&gt;WorkingMouse also offers an innovation platform which is used by multiple businesses. Since all these businesses use the same underlying platform they will all feel the benefit of improvements. For this reason, a business that starts using the platform will feel many benefits immediately, e.g. a mobile-app can operate in an offline/online mode and re-sync with the server as required. Everyone gets the capability as it's built into the platform. If a company did not want to share a new capability it is possible to fork the code base and they could continue on their own branch.&lt;/p&gt;

&lt;p&gt;However, this would mean they would then not receive any more benefits from being inside the business collective hence the innovation process slows down.&lt;/p&gt;

&lt;p&gt;👉 Visit me - &lt;a href="https://mihinduranasinghe.com/" rel="noopener noreferrer"&gt;https://mihinduranasinghe.com/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Ethical Whistleblowing</title>
      <dc:creator>Mihindu Ranasinghe</dc:creator>
      <pubDate>Sat, 25 Jul 2020 15:51:57 +0000</pubDate>
      <link>https://dev.to/mihinduranasinghe/ethical-whistleblowing-33j3</link>
      <guid>https://dev.to/mihinduranasinghe/ethical-whistleblowing-33j3</guid>
      <description>&lt;p&gt;Today we are going to have a look at Ethical Whistleblowing.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Ethical Whistleblowing ?
&lt;/h1&gt;

&lt;p&gt;Whistleblowing can be simply specified as passing on information concerning wrongdoing, such as corruption, harassment or actions believe to be misconduct, and not in line with the company’s Code of Conduct. It is the act of telling the authorities or the public that the organization you are working for is doing something immoral or illegal. This will affect your organization or government in good or bad. Whistleblowing is a valuable and powerful tool in organizational corporate governance strategy because it gives employees the way to deal with incidence of misconduct and protect the interest of individuals, organizations or public.&lt;/p&gt;

&lt;h1&gt;
  
  
  Who is a Whistleblower? ?
&lt;/h1&gt;

&lt;p&gt;A whistleblower is a person who exposes secretive information or activity within a private or public organization that is deemed illegal, unethical, or not correct.&lt;br&gt;
This can be classified into many categories violation of company policy/rules, law, regulation, or threat to public interest/national security, as well as fraud, and corruption. &lt;/p&gt;

&lt;h1&gt;
  
  
  Elements of ethical whistleblowing.
&lt;/h1&gt;

&lt;p&gt;There are 4 elements of ethical whistleblowing.&lt;/p&gt;

&lt;p&gt;1) the whistleblower&lt;br&gt;
2) the whistleblowing act or complaint&lt;br&gt;
3) the party to whom the complaint is made&lt;br&gt;
4) the organization against which the complaint is lodged&lt;/p&gt;

&lt;p&gt;There are two types of whistleblowers: internal and external. &lt;/p&gt;

&lt;p&gt;-Internal whistleblowers are those who report the misconduct, fraud, or indiscipline to senior officers of the organization. &lt;/p&gt;

&lt;p&gt;-External whistleblowers are those who report the wrongdoings to people outside the organization such as the media, public, or police. &lt;/p&gt;

&lt;p&gt;Whenever we talk about act of whistleblowing there is a name that automatically comes up in history, Edward Snowden. He was a former CIA employee who leaked classified and restricted information to the public from the United States National Security Agency in 2013.&lt;/p&gt;

&lt;p&gt;Link of a famous interview with Edward Snowden:&lt;br&gt;
&lt;a href="https://www.theguardian.com/world/2013/jun/09/edward-snowden-nsa-whistleblower-surveillance" rel="noopener noreferrer"&gt;https://www.theguardian.com/world/2013/jun/09/edward-snowden-nsa-whistleblower-surveillance&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Steps/procedure for whistleblowing
&lt;/h1&gt;

&lt;p&gt;Hire a powerful attorney:- Recruit a gifted legal advisor with involvement with dealing with informant cases can exhortation lawfully to accumulate proof against the business and secure proficient notoriety.&lt;/p&gt;

&lt;p&gt;Make sure you have evidence:- The legislature won’t pay you an award for bringing them flawed tattle of offenses, but instead explicit verification, for example, messages, inside examinations, charging records, test results, names, the contact data of included gatherings, and different types of narrative proof.&lt;/p&gt;

&lt;p&gt;File a complaint:- Informants must document an objection in court and submit it to the national government with a Disclosure Statement that subtleties the speculated unfortunate behavior.&lt;/p&gt;

&lt;p&gt;Play the waiting game:- On the off chance that the administration ought to choose to continue forward with your case, it is essential to show restraint.&lt;/p&gt;

&lt;p&gt;Prepare to be “outed”:- You need to set yourself up to be “outed” and the outcomes that it might bring. It’s prescribed to look for a new position as quickly as time permits subsequent to recording an informant guarantee.&lt;/p&gt;

&lt;p&gt;Be prepared to testify:- On the off chance that the administration chooses to make a move against your manager dependent on the consequences of its examination, you might be approached to affirm at a great jury continuing or during the preliminary. You should be set up to uncover your character, since your declaration may considerably affect the result of the case.&lt;/p&gt;

&lt;p&gt;Thank you !&lt;/p&gt;

&lt;p&gt;👉 Visit me - &lt;a href="https://mihinduranasinghe.com/" rel="noopener noreferrer"&gt;https://mihinduranasinghe.com/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Working with AJaX JSON</title>
      <dc:creator>Mihindu Ranasinghe</dc:creator>
      <pubDate>Fri, 17 Jan 2020 09:41:26 +0000</pubDate>
      <link>https://dev.to/mihinduranasinghe/working-with-ajax-json-lfn</link>
      <guid>https://dev.to/mihinduranasinghe/working-with-ajax-json-lfn</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;p&gt;IF YOU ARE NEW TO THIS ARTICLE, I RECOMMEND TO READ "Introduction To Asynchronous JavaScript" and "XmlHttpRequest (XHR) Object Request" ARTICLE BEFORE STARTING THIS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/mihinduranasinghe/introduction-to-asynchronous-javascript-351a"&gt;Introduction To Asynchronous JavaScript&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/mihinduranasinghe/xmlhttprequest-xhr-object-request-34dj"&gt;XmlHttpRequest (XHR) Object Request&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Here we are going to GET some data from a .JSON file and display them in a simple web page&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;There are two types of data in a json file to GET&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get single object data from a json file&lt;/li&gt;
&lt;li&gt;Get multiple data from an array of a json file (fetching an array)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Note:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;We have created a &lt;strong&gt;&lt;em&gt;customer.json&lt;/em&gt;&lt;/strong&gt; file with a single customer's data
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mihindu ranasinghe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"company"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CyberCatsIT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"phone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"11-222-555"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We have created a &lt;strong&gt;&lt;em&gt;customers.json&lt;/em&gt;&lt;/strong&gt; file with a multiple customers' data
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mihindu ranasinghe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"company"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CyberCatsIT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"phone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"11-222-555"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Kavindu ranasinghe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"company"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CyberCatsIT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"phone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"11-222-555"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Supun ranasinghe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"company"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CyberCatsIT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"phone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"11-222-555"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; 

&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;And a simple web page with two buttons as "Get Customer" and "Get Customers".
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"X-UA-Compatible"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"ie=edge"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.css"&lt;/span&gt; &lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;"sha256-ECB9bbROLGm8wOoEbHcHRxlHgzGqYpDtNTgDTyDz0wg="&lt;/span&gt; &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;"anonymous"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Document&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

       &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"button1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Get Customer&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"button2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Get Customers&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"output"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Customer&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"customerOutput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

       &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Customers&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"customersOutput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"app.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  👏👏&lt;strong&gt;&lt;em&gt;Let's code the JavaScript part - app.js&lt;/em&gt;&lt;/strong&gt;...
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Get single object data from the &lt;strong&gt;&lt;em&gt;customer.json&lt;/em&gt;&lt;/strong&gt; file
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;loadCustomer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//Load single customer&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;loadCustomer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;xhr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customer.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="c1"&gt;//Check Http status is Ok or not&lt;/span&gt;
            &lt;span class="c1"&gt;//Display on console&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responseText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;//Displaying on web&lt;/span&gt;
              &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responseText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

              &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
                &amp;lt;ul&amp;gt;
                    &amp;lt;li&amp;gt;ID: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;Name: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;Company: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;company&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;Phone: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;/li&amp;gt;
                &amp;lt;/ul&amp;gt;
            `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customerOutput&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Get multiple data from an array of a &lt;strong&gt;&lt;em&gt;customers.json&lt;/em&gt;&lt;/strong&gt; file (fetching an array)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;loadCustomers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//load ustomers&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;loadCustomers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;xhr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customers.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="c1"&gt;//Check Http status is Ok or not&lt;/span&gt;

            &lt;span class="c1"&gt;//Displaying on web&lt;/span&gt;
             &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responseText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
                &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;`
                &amp;lt;ul&amp;gt;
                    &amp;lt;li&amp;gt;ID: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;Name: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;Company: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;company&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;Phone: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;/li&amp;gt;
                &amp;lt;/ul&amp;gt;
            `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customersOutput&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;You can do those two functions in a single app.js file&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Output&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4p552lwvhux6itl12bhn.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4p552lwvhux6itl12bhn.PNG" alt="OutPut" width="800" height="874"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  👏👏*&lt;em&gt;This works in the similar way if you are fetching something from an external URL from a public API. For example, getting the github users from their public API. *&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;In this case we are using a local json file&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;👉What's Next?&lt;br&gt;
IF YOU HAVE DONE READING "Working with AJaX JSON" ARTICLE, I SUGGEST YOU TO READ MY NEXT ARTICLE.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=""&gt;How to use external API?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Thank You&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Hope you all enjoyed and learned something on this. Please let me know your comments suggestions and any questions you have about this blog&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;👉 Visit me - &lt;a href="https://mihinduranasinghe.com/" rel="noopener noreferrer"&gt;https://mihinduranasinghe.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>json</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>XmlHttpRequest (XHR) Object Request</title>
      <dc:creator>Mihindu Ranasinghe</dc:creator>
      <pubDate>Fri, 17 Jan 2020 04:04:40 +0000</pubDate>
      <link>https://dev.to/mihinduranasinghe/xmlhttprequest-xhr-object-request-34dj</link>
      <guid>https://dev.to/mihinduranasinghe/xmlhttprequest-xhr-object-request-34dj</guid>
      <description>&lt;h3&gt;
  
  
  &lt;strong&gt;NOTE&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;IF YOU ARE NEW TO THIS ARTICLE, I RECOMMEND TO READ "Introduction To Asynchronous JavaScript" ARTICLE BEFORE STARTING THIS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/mihinduranasinghe/introduction-to-asynchronous-javascript-351a"&gt;Introduction To Asynchronous JavaScript&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Lets code how to Get some data from a text file &amp;amp; display them in a web page using XHR Object&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Text file name "data.txt"&lt;/li&gt;
&lt;li&gt;Html page "index.html" (Only contains a button with the #id of 'button').
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"X-UA-Compatible"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"ie=edge"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.css"&lt;/span&gt; &lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;"sha256-ECB9bbROLGm8wOoEbHcHRxlHgzGqYpDtNTgDTyDz0wg="&lt;/span&gt; &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;"anonymous"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Document&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Get Data&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"output"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"app.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👏👏&lt;strong&gt;&lt;em&gt;Let's code the JavaScript part - app.js&lt;/em&gt;&lt;/strong&gt;...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;loadData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;loadData&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;

    &lt;span class="c1"&gt;//Create an XHR object&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;xhr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;//OPEN&lt;/span&gt;
    &lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data.txt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//Get Method used&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;READYSTATE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readyState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="c1"&gt;//Just to check the ready state&lt;/span&gt;

    &lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt; &lt;span class="c1"&gt;//readystate is 4 &lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;READYSTATE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readyState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="c1"&gt;//just to check the ready state&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="c1"&gt;//Check whether the http state is 200 or not&lt;/span&gt;

            &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;output&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;`&amp;lt;h1&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responseText&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/h1&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Output When press 'Get Data'&lt;/em&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1cq75h4afpr900urcttk.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1cq75h4afpr900urcttk.PNG" alt="OutPut" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;So what is "READYSTATE" and "HTTP status"&lt;/strong&gt; ??
&lt;/h3&gt;

&lt;p&gt;READYSTATE means the status of your request readyness. There are some values of ReadyState with representing several meanings.&lt;/p&gt;

&lt;p&gt;👏&lt;em&gt;ReadyState Values&lt;/em&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    0: request not initialized
    1: server connection established
    2: request received
    3: processing request
    4: request finished and response is ready
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;👏&lt;em&gt;HTTP Status&lt;/em&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    200:"OK"
    403:"Forbidden"
    404:"Not Found"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Also you can GET data using this below method instead of "xhr.onload"&lt;/strong&gt;,&lt;br&gt;
&lt;em&gt;You can try this method and get the same result&lt;/em&gt;. &lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;em&gt;NOTE&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This method is now not in use... This is a very old method. I never recommend it.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;//This one is old method&lt;/span&gt;

    &lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onreadystatechange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;READYSTATE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readyState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readyState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responseText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  👏👏&lt;strong&gt;onerror&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;You can display an error message if something bad happened to your request&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onerror&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;request error...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  👏👏&lt;strong&gt;Bonus Tip&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;when the readystate is 3&lt;/strong&gt;, that means it is in &lt;strong&gt;processing state&lt;/strong&gt;. So you can implement a &lt;strong&gt;Spinner&lt;/strong&gt; or a &lt;strong&gt;Loader&lt;/strong&gt; while processing a request. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;This code line will easily do it for you&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onprogress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt; &lt;span class="c1"&gt;//readystate is 3, u can use it for loader, spinners&lt;/span&gt;
        &lt;span class="c1"&gt;//console.log('READYSTATE', xhr.readyState);&lt;/span&gt;
        &lt;span class="c1"&gt;//Spinner or Loader&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉What's Next?&lt;br&gt;
IF YOU HAVE DONE READING "XmlHttpRequest (XHR) Object Request" ARTICLE, I SUGGEST YOU TO READ MY NEXT ARTICLE.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/mihinduranasinghe/working-with-ajax-json-lfn"&gt;How to make/code XHR Object Request using AJaX ?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Thank You&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Hope you all enjoyed and learned something on this. Please let me know your comments suggestions and any questions you have about this blog&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;👉 Visit me - &lt;a href="https://mihinduranasinghe.com/" rel="noopener noreferrer"&gt;https://mihinduranasinghe.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>xmlhttprequest</category>
    </item>
  </channel>
</rss>
