<?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: Felipe Marques</title>
    <description>The latest articles on DEV Community by Felipe Marques (@felipemsfg).</description>
    <link>https://dev.to/felipemsfg</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%2F294031%2F467dc19a-b1ef-4d95-9ea8-e39cf0893075.png</url>
      <title>DEV Community: Felipe Marques</title>
      <link>https://dev.to/felipemsfg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/felipemsfg"/>
    <language>en</language>
    <item>
      <title>Deploy an API REST .Net 5 to Google Cloud Run using Github and Google Cloud Build</title>
      <dc:creator>Felipe Marques</dc:creator>
      <pubDate>Wed, 24 Aug 2022 01:03:00 +0000</pubDate>
      <link>https://dev.to/felipemsfg/deploy-an-api-rest-net-5-to-google-cloud-run-using-github-and-google-cloud-build-3ijc</link>
      <guid>https://dev.to/felipemsfg/deploy-an-api-rest-net-5-to-google-cloud-run-using-github-and-google-cloud-build-3ijc</guid>
      <description>&lt;p&gt;Create a new &lt;code&gt;ASP.NET Core Web API&lt;/code&gt; project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fzuu8dh9giq05u1q041mj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fzuu8dh9giq05u1q041mj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give a name to the project and put it Github repo root folder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ftfb3fg7fbdsv2qrcnohu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ftfb3fg7fbdsv2qrcnohu.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select .Net version.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The version you choose here will reflect in dockerfile, so be free to change .net version but remember to adapt your dockerfile.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fdwdounvqejkmmryo3k7d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fdwdounvqejkmmryo3k7d.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select &lt;code&gt;webapi&lt;/code&gt; option to run.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F55md1pq0pv7vts9li4io.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F55md1pq0pv7vts9li4io.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run the project, make a GET resquet at &lt;code&gt;/weatherforecast&lt;/code&gt; endpoint just to test if everthing its fine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fb4nmynhc0toc4ht8hqg2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fb4nmynhc0toc4ht8hqg2.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Program.cs
&lt;/h2&gt;

&lt;p&gt;Change your &lt;code&gt;Program.cs&lt;/code&gt; to be like this code:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 csharp
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace webapi
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args)
        {
            var port = Environment.GetEnvironmentVariable("PORT") ?? "8080";
            var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development";

            if (environment == "Development")
            {
                return Host.CreateDefaultBuilder(args)
                    .ConfigureWebHostDefaults(webBuilder =&amp;gt; { webBuilder.UseStartup&amp;lt;Startup&amp;gt;(); });
            }
            else
            {
                var url = new[]
                {
                    string.Concat("http://0.0.0.0:", port)
                };
                return Host.CreateDefaultBuilder(args)
                    .ConfigureWebHostDefaults(webBuilder =&amp;gt; { webBuilder.UseStartup&amp;lt;Startup&amp;gt;().UseUrls(url); });
            }
        }
    }
}


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

&lt;/div&gt;

&lt;p&gt;In this code, its importante to set up &lt;code&gt;0.0.0.0&lt;/code&gt; IP when its running in a container, because when we use Google Cloud Run, we are running or code inside a container. In my case, I put it for every environment except the Delopment environment. &lt;/p&gt;

&lt;h2&gt;
  
  
  Dockerfile
&lt;/h2&gt;

&lt;p&gt;Create the &lt;code&gt;Dockerfile&lt;/code&gt; file in the root folder of your repo. Check if all your project files are in the root, if not, move to the root folder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fgflsvslmfj0fbvyo646x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fgflsvslmfj0fbvyo646x.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Edit your Dockerfile with the following code:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 dockerfile
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build-env
WORKDIR /app

COPY . ./
RUN dotnet publish -c Release -o out

FROM mcr.microsoft.com/dotnet/aspnet:5.0
WORKDIR /app
COPY --from=build-env /app/out .

ENV ASPNETCORE_ENVIRONMENT Production

ENTRYPOINT ["dotnet", "webapi.dll"]


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

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Remember to change de DLL file name in the last line, this name must be exactilly the name of your project main .dll file.&lt;br&gt;
If your project you another folder structure, maybe you'll need make changes in your dockerfile.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Save all files and commit.&lt;/p&gt;

&lt;h2&gt;
  
  
  GCP Cloud Run
&lt;/h2&gt;

&lt;p&gt;If you like, create a new project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F331gd0othtdnux0uxi00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F331gd0othtdnux0uxi00.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Search for &lt;code&gt;Cloud Run&lt;/code&gt;, open Cloud Run product. Create a new service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fqhaesbwsxwui2m9i0dd9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fqhaesbwsxwui2m9i0dd9.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you created a new project or is your first time using Cloud Build, maybe its necessary to Enable Cloud Build API, like me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ft9yvto97mgahuchd9wil.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ft9yvto97mgahuchd9wil.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select &lt;code&gt;Continuously deploy new revisions from a source repository&lt;/code&gt; and click &lt;code&gt;Setup With Cluod Build&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Feq9w0h3g5ip4cr89gshe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Feq9w0h3g5ip4cr89gshe.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Important: I connected my Github account previously, therefore, I couldn't take prints in this step, but if its your first time, you need to connect your Github and GCP accounts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Select your Github repository to be published.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F5opc9j2r9zkjrbzz9pjz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F5opc9j2r9zkjrbzz9pjz.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Proceed to the second step and check Dockerfile option. In &lt;code&gt;Branch&lt;/code&gt; field, keep the standard value &lt;code&gt;^main$&lt;/code&gt;, this way every commit at branch main will trigger a new build at Cloud Build to be published in Cloud Run. Keep in mind that its possible to change to another branch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fkmpmj6tcq1dzdb1vy5ie.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fkmpmj6tcq1dzdb1vy5ie.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fill the &lt;code&gt;Service name&lt;/code&gt;, I just kept default value. Choose a region, again I kept default.&lt;/p&gt;

&lt;p&gt;At &lt;em&gt;Autoscaling&lt;/em&gt; option I choose zero as minimum instances, because this reduces costs, but if you wish reduce latence and improve response time, keep in mind that probabily you will need at least one instance.&lt;/p&gt;

&lt;p&gt;As well as minimum instances, to limit the cost I choose just 1 instance at maximum. If you wish improve availabillity and reliabillity, consider increase this number according with your traffic volume&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F5a4urrjmxq2n2qb7vfu3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F5a4urrjmxq2n2qb7vfu3.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lastly, select Ingress and Authentication settings, for this tutorial I choose &lt;code&gt;Allow all traffic&lt;/code&gt; and &lt;code&gt;Allow unauthenticated invocations&lt;/code&gt;. But, for production applications, consider restrict your traffic and unauthenticated request.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvnoegaz1e1taq0nrcg6p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fvnoegaz1e1taq0nrcg6p.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Optional: Open &lt;code&gt;Container, Connections, Security&lt;/code&gt; menu and ajust your container capacity.&lt;/p&gt;

&lt;p&gt;For this deploy its not necessary to be concerned about this, and you can change this latter.&lt;/p&gt;

&lt;p&gt;Save and create your service. Wait.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F93brft7x7augjgo41tvf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F93brft7x7augjgo41tvf.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With everything done, you must get a result like bellow image:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fkewrntok2zv84g4986kq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fkewrntok2zv84g4986kq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The highlighted URL is provided by GCP and is the public URL to access your service. Try to access your &lt;code&gt;/weatherforecast&lt;/code&gt; endpoint.&lt;/p&gt;

&lt;p&gt;URL: &lt;a href="https://democsharpgcpcloudrun-lwy2plkqfa-uc.a.run.app/weatherforecast" rel="noopener noreferrer"&gt;https://democsharpgcpcloudrun-lwy2plkqfa-uc.a.run.app/weatherforecast&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvb90gf50o19il2jztm69.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fvb90gf50o19il2jztm69.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With this configuration, every new commit in your branch main in Github repository will trigger a new build at Google Cloud Build and if the build success, a new version of your application will be deployed in Google Cloud Run.&lt;/p&gt;

&lt;p&gt;The Cloud Run has a resource called Reviews that allow us to rollback a version if the new one breaks our API.&lt;/p&gt;

&lt;p&gt;In addition to allowing us to manage the traffic between version, witch allow us to deploy using canary method. Unfortunately, until now, I couldn't configure that canary to be automated with deploy, If you know how to automate traffic management during the deploy, please put in the comments.&lt;/p&gt;

&lt;p&gt;Thank you for reading and I hold this was useful.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>github</category>
      <category>cloud</category>
      <category>devops</category>
    </item>
    <item>
      <title>Como publicar uma API REST .Net 5 no Google Cloud Run usando Github e Google Cloud Build</title>
      <dc:creator>Felipe Marques</dc:creator>
      <pubDate>Wed, 24 Aug 2022 00:28:00 +0000</pubDate>
      <link>https://dev.to/felipemsfg/como-publicar-uma-api-rest-net-5-no-google-cloud-run-usando-github-e-google-cloud-build-509p</link>
      <guid>https://dev.to/felipemsfg/como-publicar-uma-api-rest-net-5-no-google-cloud-run-usando-github-e-google-cloud-build-509p</guid>
      <description>&lt;p&gt;Crie um novo projeto &lt;code&gt;ASP.NET Core Web API&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fzuu8dh9giq05u1q041mj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fzuu8dh9giq05u1q041mj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nomeie o projeto e coloque-o dentro da pasta raiz do repositório do Github.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ftfb3fg7fbdsv2qrcnohu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ftfb3fg7fbdsv2qrcnohu.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Selecione a versão do .net.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Aqui vale uma observação, a versão que você usar do .net vai influenciar como o arquivo dockerfile deverá ser configurado, se quiser escolher outra versão, fique à vontade, mas será necessário adaptar o dockerfile.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fdwdounvqejkmmryo3k7d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fdwdounvqejkmmryo3k7d.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Selecione a opção &lt;code&gt;webapi&lt;/code&gt; para execução.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F55md1pq0pv7vts9li4io.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F55md1pq0pv7vts9li4io.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Execute o projeto, faça um GET no &lt;code&gt;/weatherforecast&lt;/code&gt; apenas para validar que está tudo funcionando.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fb4nmynhc0toc4ht8hqg2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fb4nmynhc0toc4ht8hqg2.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos às adaptações necessárias no Program.cs&lt;/p&gt;

&lt;h2&gt;
  
  
  Program.cs
&lt;/h2&gt;

&lt;p&gt;Faça as alterações necessárias no seu &lt;code&gt;Program.cs&lt;/code&gt; para ficar como o do código abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Hosting&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Hosting&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;webapi&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;CreateHostBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IHostBuilder&lt;/span&gt; &lt;span class="nf"&gt;CreateHostBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PORT"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="s"&gt;"8080"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;environment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ASPNETCORE_ENVIRONMENT"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="s"&gt;"Development"&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="n"&gt;environment&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Development"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDefaultBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigureWebHostDefaults&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;webBuilder&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;webBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseStartup&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Startup&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://0.0.0.0:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;};&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDefaultBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigureWebHostDefaults&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;webBuilder&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;webBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseStartup&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Startup&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;UseUrls&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&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="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;p&gt;No código é importante notar o bloco do &lt;em&gt;else&lt;/em&gt;, nele estamos dizendo que quando o ambiente não for "Development" a aplicação deverá subir usando o IP &lt;code&gt;0.0.0.0&lt;/code&gt;, isso é necessário para que a aplicação fique visível fora do container quando publicarmos no Cloud Run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dockerfile
&lt;/h2&gt;

&lt;p&gt;Crie o &lt;code&gt;Dockerfile&lt;/code&gt; na raiz do repositório. Verifique se o seu projeto também está na raiz do repositório, se não tiver, mude para a raiz.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fgflsvslmfj0fbvyo646x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fgflsvslmfj0fbvyo646x.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Preencha seu dockerfile com o código abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;mcr.microsoft.com/dotnet/sdk:5.0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build-env&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet publish &lt;span class="nt"&gt;-c&lt;/span&gt; Release &lt;span class="nt"&gt;-o&lt;/span&gt; out

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; mcr.microsoft.com/dotnet/aspnet:5.0&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build-env /app/out .&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; ASPNETCORE_ENVIRONMENT Production&lt;/span&gt;

&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["dotnet", "webapi.dll"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Importante alterar a última linha, o nome do arquivo .dll deve ser exatamente igual à DLL principal do seu projeto.&lt;br&gt;
Se seu projeto tiver uma estrutura de pastas diferente do meu, talvez precise alterar outros pontos do dockerfile.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Salve tudo e faça commit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloud Run no GCP
&lt;/h2&gt;

&lt;p&gt;Se desejar, crie um projeto novo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F331gd0othtdnux0uxi00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F331gd0othtdnux0uxi00.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pesquise por cloud run na barra de pesquisa no meio da barra do  topo. Abra o produto Cloud Run. Crie um novo serviço.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fqhaesbwsxwui2m9i0dd9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fqhaesbwsxwui2m9i0dd9.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se você criou um projeto novo ou é a primeira vez que está usando o Cloud Build, talvez precise ativar o Cloud Build API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ft9yvto97mgahuchd9wil.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ft9yvto97mgahuchd9wil.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Selecione &lt;code&gt;Continuously deploy new revisions from a source repository&lt;/code&gt; e clique em &lt;code&gt;Setup With Cluod Build&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Feq9w0h3g5ip4cr89gshe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Feq9w0h3g5ip4cr89gshe.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Importante: eu já tinha minha conta do Github conectada ao GCP, portanto, não consegui tirar prints dessa etapa, mas se for a primeira vez sua, você terá que vincular a sua conta do Github com o GCP.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Selecione o projeto que você quer publicar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F5opc9j2r9zkjrbzz9pjz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F5opc9j2r9zkjrbzz9pjz.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Avance para segunda etapa e marque a opção Dockerfile. No campo &lt;code&gt;Branch&lt;/code&gt; deixe o valor padrão &lt;code&gt;^main$&lt;/code&gt; para que o Cloud Build seja acionado apenas quando houver commit na branch main do seu repositório, se quiser outra branch, fique à vontade.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fkmpmj6tcq1dzdb1vy5ie.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fkmpmj6tcq1dzdb1vy5ie.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Preencha o &lt;code&gt;Service name&lt;/code&gt;, eu deixei o valor padrão. Escolha uma região, para exemplo deixei a padrão.&lt;/p&gt;

&lt;p&gt;Na opção de &lt;em&gt;Autoscaling&lt;/em&gt; deixei a quantidade mínima de instâncias como zero, isso aumenta o tempo de resposta a um request, mas reduz custos, que no meu caso é mais importante. Se você quiser reduzir o tempo de resposta da sua aplicação deixe pelo menos 1 no mínimo e faça ajustes de acordo com a sua volumetria.&lt;/p&gt;

&lt;p&gt;Assim como o mínimo, deixei o máximo em 1 instância, porque novamente o mais importante para mim não é performance e sim custo. Se quiser melhorar a performance avalie aumentar o limite máximo de instâncias, mas lembre-se que isso gerará custos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F5a4urrjmxq2n2qb7vfu3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F5a4urrjmxq2n2qb7vfu3.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Por último, é preciso selecionar as configurações de Ingress e Authentication, para fins educativos deixei aberto para &lt;code&gt;Allow all traffic&lt;/code&gt; e &lt;code&gt;Allow unauthenticated invocations&lt;/code&gt;. Para aplicações em produção considere buscar mais informações para restringir o tráfego e as requisições sem autenticação.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvnoegaz1e1taq0nrcg6p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fvnoegaz1e1taq0nrcg6p.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Opcional: Abra o menu &lt;code&gt;Container, Connections, Security&lt;/code&gt; e faça ajustes no seu container em relação à memória, timeout, requests máximos por container.&lt;/p&gt;

&lt;p&gt;Para o deploy automático essas configurações são irrelevantes e você poderá alterá-las no futuro.&lt;/p&gt;

&lt;p&gt;Crie seu serviço e aguarde.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F93brft7x7augjgo41tvf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F93brft7x7augjgo41tvf.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quando estiver concluído se tudo deu certo ficará como o da imagem abaixo. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fkewrntok2zv84g4986kq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fkewrntok2zv84g4986kq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O quadro em destaque na imagem acima é a URL pública gerada pelo GCP, com ela é possível acessar nossa API no endpoint &lt;code&gt;/weatherforecast&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;URL: &lt;a href="https://democsharpgcpcloudrun-lwy2plkqfa-uc.a.run.app/weatherforecast" rel="noopener noreferrer"&gt;https://democsharpgcpcloudrun-lwy2plkqfa-uc.a.run.app/weatherforecast&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvb90gf50o19il2jztm69.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fvb90gf50o19il2jztm69.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;A partir de agora todo novo commit na main do seu repositório Github será publicado no Cloud Run&lt;/p&gt;

&lt;p&gt;O Cloud Run tem um recurso chamado Revisões, com ele é possível fazer rollback caso uma nova versão quebre algum aspecto da sua API.&lt;/p&gt;

&lt;p&gt;Além de permitir que você gerencie o tráfego entre duas ou mais versões, podendo fazer deploy canário. Infelizmente, até o momento não consegui configurar um deploy canário automático, se você souber como faz, coloca nos comentário, por favor.&lt;/p&gt;

&lt;p&gt;Obrigado por ter ficado até o fim.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>github</category>
      <category>cloud</category>
      <category>devops</category>
    </item>
    <item>
      <title>How to publish an Angular app to Firebase Hosting using Github Actions</title>
      <dc:creator>Felipe Marques</dc:creator>
      <pubDate>Sun, 21 Aug 2022 23:42:00 +0000</pubDate>
      <link>https://dev.to/felipemsfg/how-to-publish-an-angular-app-to-firebase-hosting-using-github-actions-6cf</link>
      <guid>https://dev.to/felipemsfg/how-to-publish-an-angular-app-to-firebase-hosting-using-github-actions-6cf</guid>
      <description>&lt;p&gt;The purpose of this post is to publish an Angular application within a Firebase project using the Firebase Hosting product. To automate the deploy we will use a Github Actions pipeline that will be triggered in every commit on the &lt;code&gt;main&lt;/code&gt; branch.&lt;/p&gt;

&lt;p&gt;To follow this tutorial, you will need to have:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Firebase account&lt;/li&gt;
&lt;li&gt;Google account&lt;/li&gt;
&lt;li&gt;Firebase CLI installed, see more &lt;a href="https://firebase.google.com/docs/cli#install_the_firebase_cli" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Github account&lt;/li&gt;
&lt;li&gt;Previous knowlodge of git and github&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Firebase Project
&lt;/h2&gt;

&lt;p&gt;Go to &lt;code&gt;console.firebase.google.com&lt;/code&gt; and create a new project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F5pyq14jz9a3u6doq4rwa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F5pyq14jz9a3u6doq4rwa.png" alt="Novo projeto no Firebase"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'll use &lt;code&gt;demoangulargithubactions&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fmlvwj4uj8wzoc4v9lpqm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fmlvwj4uj8wzoc4v9lpqm.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I choose to disable Google Analytics, since it's irrelevant for this tutorial.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fdb9lq88xfdxjexichj6n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fdb9lq88xfdxjexichj6n.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wait until the project creation finish.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fw9zyjv7oevupuwpplvle.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fw9zyjv7oevupuwpplvle.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As soon as the project is available, you will see a lot of products available for you. For now, keep this tab and let's go to the next step. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fa4d3c2f1foqinvcw1mlc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fa4d3c2f1foqinvcw1mlc.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Github repository and Angular project
&lt;/h2&gt;

&lt;p&gt;In this tutorial I'll create a new repository called &lt;code&gt;demogithubactions&lt;/code&gt; and a new angular project using &lt;code&gt;ng new angular-tour-of-heroes&lt;/code&gt;, but this step is optional. If you already have a project, use it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fnizxm1qsemrvy8dzxj74.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fnizxm1qsemrvy8dzxj74.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clone your repo locally. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F7gymd5iayk0v16957ohr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F7gymd5iayk0v16957ohr.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create the angular project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F0uch5y1k7qxi5wm73ank.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F0uch5y1k7qxi5wm73ank.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project will be create inside the folder &lt;code&gt;angular-tour-of-heroes&lt;/code&gt;, as image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F35spi1pzd10sq4k2lv3y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F35spi1pzd10sq4k2lv3y.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I prefer to move all code to the root folder. Just because it simplify or Github Actions pipeline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fem52izzeijx1kr81uobs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fem52izzeijx1kr81uobs.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Firebase configuration
&lt;/h2&gt;

&lt;p&gt;Now we have our project and repo, let's configurate our firebase project.&lt;/p&gt;

&lt;p&gt;If you don't have the Firebase CLI installed, do it. &lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;firebase init hosting&lt;/code&gt; and choose &lt;code&gt;Use an existing project&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F9czcl9dtjcjswehzygk6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F9czcl9dtjcjswehzygk6.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose your project in the list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F48uyhq6cxqsqpz6arxi0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F48uyhq6cxqsqpz6arxi0.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anwser the questions, be free to anwser or not like me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chosse the folder that will be publish, this need to be the same folder that the one generate when we run &lt;code&gt;ng build&lt;/code&gt;, in my case will be &lt;code&gt;dist&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fhtaktppwkm097jed9pb6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fhtaktppwkm097jed9pb6.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next, I choose No.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2F69jtfolmmdsjqxjfz7e0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F69jtfolmmdsjqxjfz7e0.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Again, I choose No, because I prefer to do the conections between Github and Firebase using my own script.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fpdt6pn60c6mipr1ixoyz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fpdt6pn60c6mipr1ixoyz.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Done. If everthing is ok, you will receive a message like the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fq9imk4579rx3c5879jg4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fq9imk4579rx3c5879jg4.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Commit everything.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F3ied182ttaz0uo660eur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F3ied182ttaz0uo660eur.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Github Actions
&lt;/h2&gt;

&lt;p&gt;To configure Github Actions, first we need an auth token from Firebase, generate this token using &lt;code&gt;firebase login:ci&lt;/code&gt;. Follow the instructions and authenticate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fkxo9fpc8ptmam9diu0aj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fkxo9fpc8ptmam9diu0aj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A token will be displayed, like image below. For now, keep this token safe, we'll put it in a Secret in your Github repo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fcwleoy0wprufmqd3vg16.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fcwleoy0wprufmqd3vg16.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Access your repo, go to Settings -&amp;gt; Secrets -&amp;gt; Actions e create a &lt;code&gt;New repository secret&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fwm60i8j5ccvu7sigco1e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fwm60i8j5ccvu7sigco1e.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Put the name &lt;code&gt;FIREBASE_TOKEN&lt;/code&gt; e paste your token in the value field. Add the Secret.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fgfmiok742davwmnwuquh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fgfmiok742davwmnwuquh.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to Actions, search for Manual e click in Configure in the Manual workflow box.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fr2wyp1bu0ryqb7rlehhw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fr2wyp1bu0ryqb7rlehhw.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A page will be create with lots of code, replece everthing with the code below.&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;Deploy-To-Firebase&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="s"&gt;main&lt;/span&gt;

  &lt;span class="na"&gt;workflow_dispatch&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;build&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;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v1&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;Use Node.js &lt;/span&gt;&lt;span class="m"&gt;16.13&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/setup-node@v1&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;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;16.13&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;Install dependencies&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;npm install&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;Build&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;npm run build -- --prod&lt;/span&gt;
    &lt;span class="pi"&gt;-&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;w9jds/firebase-action@master&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;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&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;FIREBASE_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.FIREBASE_TOKEN }}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;To save the file, click in Start Commit, follow the instructions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F4yuie9owue72nfrl21m2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F4yuie9owue72nfrl21m2.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click in Actions again, if not exist a worflow running, go to &lt;code&gt;Deploy-To-Firebase&lt;/code&gt; and click &lt;code&gt;Run workflow&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fj21aukvhdfkhl2x79h3n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fj21aukvhdfkhl2x79h3n.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Optionally, open the deploy and follow step by step. After script execution all steps need to be green, like bellow image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fbxg2isrl5mz57ucz1kki.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fbxg2isrl5mz57ucz1kki.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go back to the Firebase tab &lt;code&gt;console.firebase.google.com&lt;/code&gt; and refresh. Click &lt;code&gt;All products&lt;/code&gt; and then &lt;code&gt;Hosting&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F8v7o56ix2m68isc1a41d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F8v7o56ix2m68isc1a41d.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open one link in a new tab. Maybe you'll see something like next image, if thats the case, we need to ajust a configuration&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ffyhwl08hzambf30ax8sb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ffyhwl08hzambf30ax8sb.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to &lt;code&gt;angular.json&lt;/code&gt;, at line 23, the value of &lt;code&gt;outputPath&lt;/code&gt; configuration is different than what was informed previouslly in firebase init.&lt;/p&gt;

&lt;p&gt;Here we have two options, change file &lt;code&gt;angular.json&lt;/code&gt; and use &lt;code&gt;"outputPath": "dist"&lt;/code&gt; or change file &lt;code&gt;firebase.json&lt;/code&gt; and use &lt;code&gt;"public": "dist/angular-tour-of-heroes"&lt;/code&gt;. I choose to change &lt;code&gt;angular.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fzz5xhmgdaq3y82b41t67.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fzz5xhmgdaq3y82b41t67.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do a new commit. Follow Github Actions pipeline, refresh your Firebase console and you will see something like next image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F14x8jy960x94i0r2emtn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F14x8jy960x94i0r2emtn.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open your project link and see your project published. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fsklpnrxeyjll7zhw8a1z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fsklpnrxeyjll7zhw8a1z.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I holp that this tutorial could help you to configure a Github Action pipeline to deploy your angular project to Firebase Hosting.&lt;/p&gt;

&lt;p&gt;If you like this tutorial, try adding a &lt;a href="https://dev.to/felipemsfg/telegram-notification-with-github-actions-69m"&gt;Telegram notification with Github Actions&lt;/a&gt; step to your pipeline.&lt;/p&gt;

</description>
      <category>github</category>
      <category>devops</category>
      <category>angular</category>
      <category>firebase</category>
    </item>
    <item>
      <title>Como publicar uma aplicação Angular no Firebase usando Github Actions</title>
      <dc:creator>Felipe Marques</dc:creator>
      <pubDate>Sun, 21 Aug 2022 23:01:00 +0000</pubDate>
      <link>https://dev.to/felipemsfg/como-publicar-uma-aplicacao-angular-no-firebase-usando-github-actions-41dm</link>
      <guid>https://dev.to/felipemsfg/como-publicar-uma-aplicacao-angular-no-firebase-usando-github-actions-41dm</guid>
      <description>&lt;p&gt;O objetivo desse post é publicar uma aplicação Angular dentro de um projeto do Firebase utilizando o produto Hosting do Firebase. Para fazer automatizar a publicação configuraremos um script do  Github Actions para ser executado sempre que houver um commit na branch &lt;code&gt;main&lt;/code&gt; do repositório.&lt;/p&gt;

&lt;p&gt;Para acompanhar os passos desse post, será necessário que você tenha:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Conta do Firebase&lt;/li&gt;
&lt;li&gt;Conta do Google&lt;/li&gt;
&lt;li&gt;Firebase CLI instalado, veja como &lt;a href="https://firebase.google.com/docs/cli#install_the_firebase_cli"&gt;aqui&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Conta do Github&lt;/li&gt;
&lt;li&gt;Conhecimento para criar e trabalhar com um repositório no Github&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Projeto no Firebase
&lt;/h2&gt;

&lt;p&gt;Acesse o console do Firebase em &lt;code&gt;console.firebase.google.com&lt;/code&gt; e crie um novo projeto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jgLRUCyG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5pyq14jz9a3u6doq4rwa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jgLRUCyG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5pyq14jz9a3u6doq4rwa.png" alt="Novo projeto no Firebase" width="346" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No meu caso vou usar o nome &lt;code&gt;demoangulargithubactions&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rj7ycT-O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mlvwj4uj8wzoc4v9lpqm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rj7ycT-O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mlvwj4uj8wzoc4v9lpqm.png" alt="Image description" width="842" height="712"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E vou optar por não habilitar o Google Analytics, uma vez que é irrelevante para esse tutorial.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hiS2-gff--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/db9lq88xfdxjexichj6n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hiS2-gff--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/db9lq88xfdxjexichj6n.png" alt="Image description" width="819" height="817"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aguarde alguns instantes até que o projeto seja criado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--czsqnyFf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w9zyjv7oevupuwpplvle.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--czsqnyFf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w9zyjv7oevupuwpplvle.png" alt="Image description" width="392" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Assim que o projeto estiver disponível você terá a opção de utilizar alguns produtos, por hora deixe essa aba aberta e vamos para a próxima etapa. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B8yToRzF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a4d3c2f1foqinvcw1mlc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B8yToRzF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a4d3c2f1foqinvcw1mlc.png" alt="Image description" width="880" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Criar repositório no github e projeto Angular
&lt;/h2&gt;

&lt;p&gt;Para esse tutorial vou criar um repositório novo chamado &lt;code&gt;demogithubactions&lt;/code&gt; e um projeto angular novo usando &lt;code&gt;ng new angular-tour-of-heroes&lt;/code&gt;, mas essa etapa é opcional. Se você já tem um projeto, continue com ele.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BsQN7sGm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nizxm1qsemrvy8dzxj74.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BsQN7sGm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nizxm1qsemrvy8dzxj74.png" alt="Image description" width="773" height="865"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Faça o clone do seu repositório localmente.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_cEutK35--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7gymd5iayk0v16957ohr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_cEutK35--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7gymd5iayk0v16957ohr.png" alt="Image description" width="798" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Crie o projeto angular&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gUtKIwQx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0uch5y1k7qxi5wm73ank.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gUtKIwQx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0uch5y1k7qxi5wm73ank.png" alt="Image description" width="880" height="196"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O projeto será criado dentro da pasta &lt;code&gt;angular-tour-of-heroes&lt;/code&gt; como na imagem abaixo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--du8LpLLd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/35spi1pzd10sq4k2lv3y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--du8LpLLd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/35spi1pzd10sq4k2lv3y.png" alt="Image description" width="781" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No meu caso vou mover todo o código para a pasta raiz. Se você quiser organizar de outra forma, lembre-se que o script do Github Actions precisará de algumas alterações.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pfDjguTR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/em52izzeijx1kr81uobs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pfDjguTR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/em52izzeijx1kr81uobs.png" alt="Image description" width="802" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuração do Firebase
&lt;/h2&gt;

&lt;p&gt;Pronto, agora que já temos o projeto Angular e o repositório prontos, vamos configurar o Firebase.&lt;/p&gt;

&lt;p&gt;Se você ainda não fez, faça a instalação do Firebase CLI e o login na sua conta.&lt;/p&gt;

&lt;p&gt;Depois, execute o comando &lt;code&gt;firebase init hosting&lt;/code&gt; e escolha a opção &lt;code&gt;Usar um projeto existente&lt;/code&gt; (talvez esteja em inglês: Use an existing project)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Za1MTDps--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9czcl9dtjcjswehzygk6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Za1MTDps--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9czcl9dtjcjswehzygk6.png" alt="Image description" width="695" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Será mostrado a lista de projetos da sua conta, escolha o projeto que você quer fazer o deploy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Nnw7sjuN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/48uyhq6cxqsqpz6arxi0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nnw7sjuN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/48uyhq6cxqsqpz6arxi0.png" alt="Image description" width="546" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A partir de agora, serão feitas algumas perguntas, vamos lá:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Escolha a pasta que será publicada, essa é a mesma pasta onde o comando &lt;code&gt;ng build&lt;/code&gt; gera os arquivos de publicação, no nosso caso será a pasta &lt;code&gt;dist&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Up5k0BDL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/htaktppwkm097jed9pb6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Up5k0BDL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/htaktppwkm097jed9pb6.png" alt="Image description" width="781" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Em seguida perguntam se quer configurar sua página como single-page app, eu sempre opto por &lt;code&gt;N&lt;/code&gt;, não sei qual a influência dessa opção no roteamente do angular, se alguém souber, me fala nos comentários, por favor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZqD7ZqLy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/69jtfolmmdsjqxjfz7e0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZqD7ZqLy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/69jtfolmmdsjqxjfz7e0.png" alt="Image description" width="771" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aqui também marco que não, porque nosso script já vai fazer a conexão com o Github Actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fmxvx2VV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pdt6pn60c6mipr1ixoyz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fmxvx2VV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pdt6pn60c6mipr1ixoyz.png" alt="Image description" width="580" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pronto, se as configurações foram criadas com sucesso, você terá uma mensagem similiar com a da imagem abaixo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nanx6nIA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q9imk4579rx3c5879jg4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nanx6nIA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q9imk4579rx3c5879jg4.png" alt="Image description" width="537" height="215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Faça commit de tudo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--74o4i8ZM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ied182ttaz0uo660eur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--74o4i8ZM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ied182ttaz0uo660eur.png" alt="Image description" width="305" height="812"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configurando o Github Actions
&lt;/h2&gt;

&lt;p&gt;Para configurar o Github Actions vamos precisar primeiro de um token de autenticação do Firebase, gere esse token executando o comando &lt;code&gt;firebase login:ci&lt;/code&gt;. Uma tela do browser deve abrir e você precisará se autenticar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mrFqHSH6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kxo9fpc8ptmam9diu0aj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mrFqHSH6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kxo9fpc8ptmam9diu0aj.png" alt="Image description" width="541" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se tudo der certo um token será gerado, na imagem abaixo eu pintei a linha, mas é possível ver que é uma string, guarde esse token por enquanto, vamos colocá-lo em um Secret do repositório no Github.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y2msCr21--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cwleoy0wprufmqd3vg16.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y2msCr21--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cwleoy0wprufmqd3vg16.png" alt="Image description" width="796" height="218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Acesse o seu repositório no Github, vá em Settings -&amp;gt; Secrets -&amp;gt; Actions e crie um &lt;code&gt;New repository secret&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hz7r2aw_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wm60i8j5ccvu7sigco1e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hz7r2aw_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wm60i8j5ccvu7sigco1e.png" alt="Image description" width="880" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Coloque o nome de &lt;code&gt;FIREBASE_TOKEN&lt;/code&gt; e no valor cole o token gerado na etapa anterior. Adicione o Secret.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LZk1rcgj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gfmiok742davwmnwuquh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LZk1rcgj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gfmiok742davwmnwuquh.png" alt="Image description" width="602" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Acesse a aba Actions, pesquise por Manual e clique em Configure na caixa do Manual workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mQSNd6Sr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r2wyp1bu0ryqb7rlehhw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mQSNd6Sr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r2wyp1bu0ryqb7rlehhw.png" alt="Image description" width="880" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A página que será aberta já vem com algum código, substitua tudo pelo código abaixo.&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;Deploy-To-Firebase&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="s"&gt;main&lt;/span&gt;

  &lt;span class="na"&gt;workflow_dispatch&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;build&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;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v1&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;Use Node.js &lt;/span&gt;&lt;span class="m"&gt;16.13&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/setup-node@v1&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;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;16.13&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;Install dependencies&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;npm install&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;Build&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;npm run build -- --prod&lt;/span&gt;
    &lt;span class="pi"&gt;-&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;w9jds/firebase-action@master&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;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&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;FIREBASE_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.FIREBASE_TOKEN }}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Salve o arquivo clicando em Start Commit e faça o commit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rhha6Imt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4yuie9owue72nfrl21m2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rhha6Imt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4yuie9owue72nfrl21m2.png" alt="Image description" width="880" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clique em actions novamente e veja se já existe algum workflow sendo executado, se não tiver, vá em &lt;code&gt;Deploy-To-Firebase&lt;/code&gt; e clique em &lt;code&gt;Run workflow&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gdRalCqC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j21aukvhdfkhl2x79h3n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gdRalCqC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j21aukvhdfkhl2x79h3n.png" alt="Image description" width="880" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Opcionalmente, abra o deploy e acompanhe a execução de cada etapa. Se tudo funcionou, você terá uma tela com todas as etapas verdes, como a imagem abaixo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w14lZolM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bxg2isrl5mz57ucz1kki.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w14lZolM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bxg2isrl5mz57ucz1kki.png" alt="Image description" width="880" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Volte na aba do Firebase &lt;code&gt;console.firebase.google.com&lt;/code&gt; que você deixou aberta e atualize. Clique em &lt;code&gt;All products&lt;/code&gt; e depois em &lt;code&gt;Hosting&lt;/code&gt; e você verá uma tela similar à da próxima image. Com dois domínios disponíveis e o pacote que foi publicado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TKNOawIn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8v7o56ix2m68isc1a41d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TKNOawIn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8v7o56ix2m68isc1a41d.png" alt="Image description" width="880" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Abra um dos domínios e você deve ver uma imagem como a abaixo. Se isso aconteceu com você, é porque precisamos de um ajuste de configuração.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jdVPId0M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fyhwl08hzambf30ax8sb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jdVPId0M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fyhwl08hzambf30ax8sb.png" alt="Image description" width="880" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Abaixo você pode ver o conteúdo do meu arquivo &lt;code&gt;angular.json&lt;/code&gt;, na linha 23, a configuração &lt;code&gt;outputPath&lt;/code&gt; está configurado para um diretório diferente do que foi informado na hora que configurei o firebase.&lt;/p&gt;

&lt;p&gt;Aqui temos duas opções, alterar o arquivo &lt;code&gt;angular.json&lt;/code&gt; e colocar &lt;code&gt;"outputPath": "dist"&lt;/code&gt; ou alterar o arquivo firebase.json e colocar &lt;code&gt;"public": "dist/angular-tour-of-heroes"&lt;/code&gt;. Eu preferi alterar o meu &lt;code&gt;angular.json&lt;/code&gt;. Fique à vontade.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_ZBfUOv7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zz5xhmgdaq3y82b41t67.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_ZBfUOv7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zz5xhmgdaq3y82b41t67.png" alt="Image description" width="880" height="709"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Faça a correção e um novo commit. Você verá que foi gerado um novo build. Se tudo correu bem, um novo pacote foi entregue no seu projeto firebase, como na imagem abaixo. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fy2KPiN2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/14x8jy960x94i0r2emtn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fy2KPiN2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/14x8jy960x94i0r2emtn.png" alt="Image description" width="880" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Observe que agora você tem dois pacotes e existe a opção de voltar para o pacote anterior clicando no botão no início da linha do deploy mais antigo.&lt;/p&gt;

&lt;p&gt;Observe também que o número de arquivos do último deploy está zero. Isso acontece porque há uma certa demora para o Firebase atualizar esse número.&lt;/p&gt;

&lt;p&gt;O mais importante é que se você acessar um dos dois domínios, deve ver o projeto publicado, como na imagem a seguir.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8jse5FGN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sklpnrxeyjll7zhw8a1z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8jse5FGN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sklpnrxeyjll7zhw8a1z.png" alt="Image description" width="880" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Espero que esse passo a passo tenha ajudado a configurar um projeto do angular no firebase.&lt;/p&gt;

&lt;p&gt;Aproveite e adicione uma etapa de &lt;a href="https://dev.to/felipemsfg/telegram-notification-with-github-actions-69m"&gt;notificação no seu pipeline do Github Actions utilizando o Telegram&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>github</category>
      <category>firebase</category>
      <category>devops</category>
    </item>
    <item>
      <title>Como iniciar em C# e Angular - Referências</title>
      <dc:creator>Felipe Marques</dc:creator>
      <pubDate>Thu, 04 Aug 2022 03:32:08 +0000</pubDate>
      <link>https://dev.to/felipemsfg/como-iniciar-em-c-e-angular-referencias-3ok1</link>
      <guid>https://dev.to/felipemsfg/como-iniciar-em-c-e-angular-referencias-3ok1</guid>
      <description>&lt;p&gt;Recentemente um amigo me pediu ajuda para iniciar na área de desenvolvimento de software, ele queria ajuda para procurar cursos, livros e outros materiais.&lt;/p&gt;

&lt;p&gt;Após conversarmos, também ficou claro que ele precisaria de ajuda para criar um &lt;a href="https://pt.wikipedia.org/wiki/Roadmap"&gt;roadmap&lt;/a&gt; de estudos.&lt;/p&gt;

&lt;p&gt;Após coletar algumas indicações de outros amigos com os quais já trabalhei, ao invés de enviá-las por Whatsapp para meu amigo, decidi escrever esse post para que todas as recomendações fiquem reunidas e minimamente organizadas para consultas futuras, não só do meu amigo, mas para todas as pessoas que também desejam começar a programar, especialmente se o foco for desenvolvimento Web com C# e Angular.&lt;/p&gt;

&lt;p&gt;O objetivo é desse material é evoluir com indicações, então ajude-nos colocando indicações e sugestões nos comentários.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lógica de Programação
&lt;/h2&gt;

&lt;p&gt;Embora seja um pouco teórico e aparentemente chato para quem está começando, é um assunto super importante e será necessário independente da linguagem que você for programar. Então investe um tempo nesse curso.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLHz_AreHm4dmSj0MHol_aoNYCSGFqvfXV"&gt;Lógica de Programação&lt;/a&gt;&lt;br&gt;
Disponível no Youtube (gratuito)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Quando já tiver visto toda a teoria, que tal tentar um curso que aplica lógica de programação na prática usando C#?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLOky0hrmU5at0MPXKZtUJ4lZDLxP0IMIF"&gt;C# - Lógica de Programação&lt;/a&gt;&lt;br&gt;
Disponível no Youtube (gratuito)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E para se aprofundar, porque não mergulhar nesse livro &lt;a href="https://www.caelum.com.br/apostila/apostila-csharp-orientacao-objetos.pdf"&gt;C# e Orientação a Objetos - Caelum&lt;/a&gt; distribuido gratuitamente pela Caelum.&lt;/p&gt;

&lt;p&gt;Após ter alguma familiaridade com os temas acima, indicaria um curso &lt;a href="https://pt.stackoverflow.com/questions/52450/o-que-%C3%A9-e-o-que-faz-um-full-stack-web-developer"&gt;Fullstack&lt;/a&gt; e por indicação deixo o link abaixo. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.udemy.com/course/angular-dotnetcore-efcore/"&gt;Fullstack com .Net Web API e Angular&lt;/a&gt;&lt;br&gt;
Disponível na Udemy (pago)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Versionamento de código
&lt;/h2&gt;

&lt;p&gt;Paralelamente ao aprendizado da linguagem de programação, eu indico ainda ir se familiarizando com versionadores de código, principalmente o Git. E para isso indico usar o Github, por ainda ser a plataforma mais difundida.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.udemy.com/course/git-e-github-para-iniciantes/"&gt;Git e Github para iniciantes&lt;/a&gt;&lt;br&gt;
Disponível na Udemy (gratuito)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;Além do conteúdo acima, vou deixar algumas referências aqui.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://balta.io/carreiras/desenvolvedor-backend-dotnet"&gt;Carreira Desenvolvedor Backend .NET - balta.io&lt;/a&gt;&lt;br&gt;
Conteúdo free e pago&lt;/p&gt;

&lt;p&gt;&lt;a href="https://balta.io/carreiras/desenvolvedor-frontend-angular"&gt;Carreira Desenvolvedor Frontend Angular - balta.io&lt;/a&gt;&lt;br&gt;
Conteúdo free e pago&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>csharp</category>
      <category>angular</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Visual Studio breakpoint com condições</title>
      <dc:creator>Felipe Marques</dc:creator>
      <pubDate>Wed, 29 Jun 2022 13:00:48 +0000</pubDate>
      <link>https://dev.to/felipemsfg/visual-studio-breakpoint-com-condicoes-7gg</link>
      <guid>https://dev.to/felipemsfg/visual-studio-breakpoint-com-condicoes-7gg</guid>
      <description>&lt;p&gt;🇺🇸 &lt;a href="https://dev.to/felipemsfg/visual-studio-breakpoint-with-conditions-4ln9"&gt;English version&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essa é uma dica simple e rápida, talvez você já conheça, mas eu não conhecia, mesmo após 10 anos trabalhando diariamente com o visual studio e o C#.&lt;/p&gt;

&lt;p&gt;Se você já teve que debugar um código que é executado várias vezes buscando avaliar o comportamento do seu código em apenas uma determinada condição, você já precisou de algo como um breakpoint com condições. E como o próprio nome diz, é esse recurso que o VS fornece para nós.&lt;/p&gt;

&lt;p&gt;Para exemplificar, fiz um código simples que imprime 10 números aleatórios em um console.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Console.WriteLine("Begin");
var rnd = new Random();

for (int i = 1; i &amp;lt;= 10; i++)
{
    Console.WriteLine($"{i}: {rnd.Next(10)}");
}

Console.WriteLine("End");
Console.ReadLine();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Se você colocar um breakpoint, como na imagem abaixo, o debug vai parar nele em todas as 10 execuções do loop.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NE1LHfjv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iyuothc7dk6u1ybb43ch.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NE1LHfjv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iyuothc7dk6u1ybb43ch.png" alt="Image description" width="547" height="189"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Entretanto, você pode querer observar apenas o compotamento do loop quando a variável &lt;code&gt;i==5&lt;/code&gt;, nesse caso, clique com o botão direito em cima do breakpoint e adicione uma condição.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8ZzOh090--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bnsvougtou82aawaqdjj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8ZzOh090--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bnsvougtou82aawaqdjj.png" alt="Image description" width="537" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As condições são informada como na linguagem e você pode qualquer variável disponível naquele escopo, nesse caso, estou usando a variável &lt;code&gt;i&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O_682INF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4e5schs19jk2mn7gjc6l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O_682INF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4e5schs19jk2mn7gjc6l.png" alt="Image description" width="880" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ux09eGZT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1mnhpxjqj0m8u57d2f3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ux09eGZT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1mnhpxjqj0m8u57d2f3e.png" alt="Image description" width="880" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aqui tem um vídeo de exemplo do processo todo.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/8a0910dd9ca84d5892e31128d91c4795"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;Espero que tenha gostado e se você não conhecia esse recurso, comenta aí.&lt;/p&gt;

</description>
      <category>breakpoint</category>
      <category>debug</category>
      <category>visualstudio</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Visual Studio breakpoint with conditions</title>
      <dc:creator>Felipe Marques</dc:creator>
      <pubDate>Wed, 29 Jun 2022 12:59:48 +0000</pubDate>
      <link>https://dev.to/felipemsfg/visual-studio-breakpoint-with-conditions-4ln9</link>
      <guid>https://dev.to/felipemsfg/visual-studio-breakpoint-with-conditions-4ln9</guid>
      <description>&lt;p&gt;🇧🇷 &lt;a href="https://dev.to/felipemsfg/visual-studio-breakpoint-com-condicoes-7gg"&gt;Versão em português&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a simple and quick tip, maybe you already know it, but I don't, even after 10 years working daily with visual studio and C#, so I decided write about it.&lt;/p&gt;

&lt;p&gt;If you've ever had to debug code that takes several attempts to evaluate behavior on just a certain condition, you already needed something like a breakpoint with conditions. And as its name says, VS provides this feature for us.&lt;/p&gt;

&lt;p&gt;To exemplify, I made a simple code that prints 10 random numbers on a console.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Console.WriteLine("Begin");
var rnd = new Random();

for (int i = 1; i &amp;lt;= 10; i++)
{
    Console.WriteLine($"{i}: {rnd.Next(10)}");
}

Console.WriteLine("End");
Console.ReadLine();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you put a breakpoint, as in the image below, the debug will stop at it all 10 executions of the loop.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fiyuothc7dk6u1ybb43ch.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fiyuothc7dk6u1ybb43ch.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, you can must observe the loop behavior just when the condition is &lt;code&gt;i==5&lt;/code&gt;, in this case, right click on the breakpoint and put your condition.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fbnsvougtou82aawaqdjj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fbnsvougtou82aawaqdjj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The conditions are specified as in the language and you can use any variable available in that scope, in this case I'm using the &lt;code&gt;i&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F4e5schs19jk2mn7gjc6l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F4e5schs19jk2mn7gjc6l.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F1mnhpxjqj0m8u57d2f3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F1mnhpxjqj0m8u57d2f3e.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a simple example video of the whole process.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/8a0910dd9ca84d5892e31128d91c4795"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;I hope you like and if you don't know this feature, comment there.&lt;/p&gt;

</description>
      <category>visualstudio</category>
      <category>debug</category>
      <category>breakpoint</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Telegram notification with Github Actions</title>
      <dc:creator>Felipe Marques</dc:creator>
      <pubDate>Mon, 08 Nov 2021 15:01:42 +0000</pubDate>
      <link>https://dev.to/felipemsfg/telegram-notification-with-github-actions-69m</link>
      <guid>https://dev.to/felipemsfg/telegram-notification-with-github-actions-69m</guid>
      <description>&lt;p&gt;🇧🇷 &lt;a href="https://dev.to/felipemsfg/telegram-github-actions-26nj"&gt;Versão em português&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use the following script to receive Telegram notifications always your Github Actions is running.&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="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;Send Telegram Message Ok&lt;/span&gt;
        &lt;span class="s"&gt;uses&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appleboy/telegram-action@master&lt;/span&gt;
        &lt;span class="s"&gt;env&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;GITHUB_CONTEXT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ toJSON(github) }}&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;to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.TELEGRAM_ID }}&lt;/span&gt;
          &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.TELEGRAM_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;markdown&lt;/span&gt;
          &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;*1st line of your message with bold*&lt;/span&gt;
            &lt;span class="s"&gt;*2nd line of your message with bold, too*&lt;/span&gt;
            &lt;span class="s"&gt;Application: *Write something to be put inside your message*. The below lines still are part of your message.          &lt;/span&gt;
            &lt;span class="s"&gt;Branch: *${{ github.ref }}*&lt;/span&gt;
            &lt;span class="s"&gt;Repository: *${{ github.repository }}*&lt;/span&gt;
            &lt;span class="s"&gt;Owner: *${{ github.repository_owner }}*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to go deeper into this component, &lt;a href="https://github.com/appleboy/telegram-action" rel="noopener noreferrer"&gt;go to project's github repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see, to use this component we need two important informations, the &lt;strong&gt;TELEGRAM_ID&lt;/strong&gt; and the &lt;strong&gt;TELEGRAM_TOKEN&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To get your &lt;code&gt;TELEGRAM_TOKEN&lt;/code&gt;, you will need to create a telegram's bot, do that starting a conversation with &lt;code&gt;BotFather&lt;/code&gt;. Start a new conversation and search for &lt;code&gt;@botfather&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fxexc893xpukek2lxjy1n.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fxexc893xpukek2lxjy1n.jpg" alt="BotFather"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can start the conversation sending a &lt;code&gt;/help&lt;/code&gt; message to see all options allowed. But if you want to skip this step, just send &lt;code&gt;/newbot&lt;/code&gt; and follow the instructions. When finish bot's creation, you will receive a message with your bot's token, as show below:&lt;br&gt;
&lt;a href="https://media.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%2Fj70dhdsrcm1ettrbjhf9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fj70dhdsrcm1ettrbjhf9.jpg" alt="TELEGRAM_TOKEN"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Good job! Now you got your &lt;code&gt;TELEGRAM_TOKEN&lt;/code&gt;, in this example it is &lt;code&gt;2063069520:AAE7Gcummn9fSp_xLQH7dBGihpzOyWQCm9g&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, let's find out your &lt;code&gt;TELEGRAM_ID&lt;/code&gt;. Just search for &lt;code&gt;@userinfobot&lt;/code&gt; and start a conversation with &lt;code&gt;/star&lt;/code&gt; message. The result message will be like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@your_telegram_username
Id: 12345678
First: &amp;lt;Your Firstname&amp;gt;
Last: &amp;lt;Your Lastname&amp;gt;
Lang: en-US
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your TELEGRAM_ID is the number in second line, right between your &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;firstname&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In this point you have all information to start sending notification messages at any pipeline in Github Actions.&lt;/p&gt;

&lt;p&gt;Just add these information to repository secrets.&lt;/p&gt;

</description>
      <category>github</category>
      <category>devops</category>
      <category>gha</category>
    </item>
    <item>
      <title>Angular: Environment</title>
      <dc:creator>Felipe Marques</dc:creator>
      <pubDate>Mon, 01 Nov 2021 00:40:20 +0000</pubDate>
      <link>https://dev.to/felipemsfg/angular-environment-mbp</link>
      <guid>https://dev.to/felipemsfg/angular-environment-mbp</guid>
      <description>&lt;p&gt;As variáveis de ambiente permitem que nós possamos incluir no nosso código condições, parâmetros e valores diferentes de acordo com nosso ambiente. &lt;/p&gt;

&lt;p&gt;Imagine que você utilize uma API Rest de um serviço qualquer, seja ele criado internamente na empresa que você trabalha, seja ele de terceiros e que esse serviço ofereça um endpoint para homologação e outro para produção.&lt;/p&gt;

&lt;p&gt;Uma abordagem inicial seria trocar os valores dessa api todas as vezes que quisermos publicar nossa aplicação em produção.&lt;/p&gt;

&lt;p&gt;Uma abordagem muito mais elegante é configurar as variáveis de ambiente para que você não tenha que lembrar de trocar o conteúdo de nenhuma variável.&lt;/p&gt;

&lt;p&gt;Aqui mostro como fazer isso utilizando o recurso de configuração de ambiente do Angular.&lt;/p&gt;

&lt;p&gt;Projetos criados com Angular CLI possuem por padrão um arquivo de configuração chamado environment.ts disponível na pasta environments da sua aplicação.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9e6z5mc01p2k9ndi64au.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9e6z5mc01p2k9ndi64au.png" alt="Arquivos environment.ts e environment.prod.ts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;environment.ts:&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;production&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;environment.prod.ts&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;production&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Veja um exemplo de como usar o environment.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../environments/environment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&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;"row justify-content-center"&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"!environment.production"&lt;/span&gt;&lt;span class="nt"&gt;&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;"auth-box text-center"&lt;/span&gt;&lt;span class="nt"&gt;&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;"row"&lt;/span&gt;&lt;span class="nt"&gt;&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;"col-md-12"&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;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"LimparTudo()"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-danger btn-md btn-block waves-effect text-center m-b-20"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Limpar Memória&lt;span class="nt"&gt;&amp;lt;/button&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;/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;/div&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Publicação automática de um app flutter na PlayStore com Github Actions</title>
      <dc:creator>Felipe Marques</dc:creator>
      <pubDate>Mon, 01 Nov 2021 00:02:16 +0000</pubDate>
      <link>https://dev.to/felipemsfg/publicacao-automatica-de-um-app-flutter-na-playstore-com-github-actions-i4b</link>
      <guid>https://dev.to/felipemsfg/publicacao-automatica-de-um-app-flutter-na-playstore-com-github-actions-i4b</guid>
      <description>&lt;p&gt;O objetivo desse post é detalhar o passo a passo para publicar uma aplicação Flutter na Play Store.&lt;/p&gt;

&lt;h2&gt;
  
  
  Publicação da 1ª release do app
&lt;/h2&gt;

&lt;p&gt;A primeira publicação deve ser feita manualmente e só depois de aprovado pela PlayStore que será possível fazer o deploy totalmente automatizado.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Crie a chave no Android Studio
&lt;/h3&gt;

&lt;p&gt;Abra o Android Studio, acesse &lt;code&gt;Build/Generate Signed Bundle or Apk&lt;/code&gt;, na próxima tela escolha &lt;code&gt;Android App Bundle&lt;/code&gt; e clique em Next. Clique em &lt;code&gt;Create new...&lt;/code&gt; para criar uma key store nova.&lt;/p&gt;

&lt;p&gt;Lembre-se de guardar o conteúdo que for utilizado nos campos de senha e no campo &lt;code&gt;Alias&lt;/code&gt;. Você vai precisar deles depois.&lt;br&gt;
A imagem abaixo mostra um exemplo de como preencher os dados.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F61qq7msloa0yqezlbkv6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F61qq7msloa0yqezlbkv6.png" alt="Geração da chave"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Gere o base64 da chave
&lt;/h3&gt;

&lt;p&gt;Após concluir a geração da chave, abra o terminal do seu SO e execute os comandos abaixo. Obs: Se estiver no Windows, talvez precise instalar o openssl antes. Talvez esse &lt;a href="https://stackoverflow.com/questions/50625283/how-to-install-openssl-in-windows-10" rel="noopener noreferrer"&gt;link do StackOverflow&lt;/a&gt; possa te ajudar.&lt;/p&gt;

&lt;p&gt;Uma vez que você esteja com o arquivo myapp.jks disponível, execute o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openssl &lt;span class="nb"&gt;base64&lt;/span&gt; &amp;lt; myapp.jks | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'\n'&lt;/span&gt; | &lt;span class="nb"&gt;tee &lt;/span&gt;myapp.jks.base64.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assim como as senhas e o Alias, você vai precisar do conteúdo desse arquivo quando for configurar os secrets do pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Crie um pipeline de build no gha
&lt;/h3&gt;

&lt;p&gt;Nesse primeiro momento, o pipeline fará apenas o build do arquivo &lt;code&gt;.aab&lt;/code&gt;, sem fazer o deploy para a Play Store.&lt;/p&gt;

&lt;p&gt;O objetivo desse pipeline é criar o &lt;code&gt;.aab&lt;/code&gt; assinado que você usará para subir na PlayStore. Mas você pode fazer isso pelo seu ambiente de desenvolvimento se quiser. Particularmente eu prefiro gerar pelo GhA para já testar essa etapa do script.&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;Build&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="s"&gt;main&lt;/span&gt;

&lt;span class="c1"&gt;# the follow line allow this script to be started manually.&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&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;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# This job will run on ubuntu virtual machine&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="c1"&gt;# Setup Java environment in order to build the Android app.&lt;/span&gt;
      &lt;span class="pi"&gt;-&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@v1&lt;/span&gt;
      &lt;span class="pi"&gt;-&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/setup-java@v1&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;java-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;12.x"&lt;/span&gt;

      &lt;span class="c1"&gt;# Setup the flutter environment.&lt;/span&gt;
      &lt;span class="pi"&gt;-&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;subosito/flutter-action@v1&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;# channel: 'beta' # 'dev', 'alpha', default to: 'stable'&lt;/span&gt;
          &lt;span class="na"&gt;flutter-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2.2.3"&lt;/span&gt; &lt;span class="c1"&gt;# you can also specify exact version of flutter&lt;/span&gt;

      &lt;span class="c1"&gt;# Get flutter dependencies.&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;flutter pub get&lt;/span&gt;

      &lt;span class="c1"&gt;# Build appbundle.&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;flutter build appbundle --target-platform android-arm,android-arm64,android-x64 --no-sound-null-safety&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;zip -d build/app/outputs/bundle/release/app-release.aab META-INF/\*&lt;/span&gt;

      &lt;span class="pi"&gt;-&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;r0adkll/sign-android-release@v1&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;Sign app APK&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;sign_app&lt;/span&gt; &lt;span class="c1"&gt;# ID used to access action output&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;releaseDirectory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build/app/outputs/bundle/release&lt;/span&gt;
          &lt;span class="na"&gt;signingKeyBase64&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.KEY }}&lt;/span&gt;
          &lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.ALIAS }}&lt;/span&gt;
          &lt;span class="na"&gt;keyStorePassword&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.KEY_STORE_PASSWORD }}&lt;/span&gt;
          &lt;span class="na"&gt;keyPassword&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.KEY_PASSWORD }}&lt;/span&gt;

      &lt;span class="c1"&gt;# Upload generated apk to the artifacts.&lt;/span&gt;
      &lt;span class="pi"&gt;-&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/upload-artifact@v1&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;Upload Artifact&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release-aab&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build/app/outputs/bundle/release/app-release.aab&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Configure os secrets do pipeline
&lt;/h3&gt;

&lt;p&gt;Com o script criado, você vai precisar configurar as secrets. É nesse momento que você vai precisar das informações geradas nos passos 1 e 2.&lt;/p&gt;

&lt;p&gt;Pelo site do Github, vá no repositório do projeto e acesse o menu &lt;code&gt;Settings -&amp;gt; Secrets&lt;/code&gt;, abrirá uma página como da imagem abaixo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fmlr53anxbxcpynr0yrqc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fmlr53anxbxcpynr0yrqc.png" alt="Repositório sem nenhuma secret criada"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cadastre as secrets conforme as orientações abaixo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;KEY: conteúdo do arquivo myapp.jks.base64.txt&lt;/li&gt;
&lt;li&gt;ALIAS: o valor que você preencheu ao criar a chave&lt;/li&gt;
&lt;li&gt;KEY_STORE_PASSWORD: a senha que você usou ao criar a chave&lt;/li&gt;
&lt;li&gt;KEY_PASSWORD: a senha que você usou ao criar a chave&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com todos os passos realizados, você deve ser capaz de executar seu pipeline com sucesso e isso irá gerar um arquivo &lt;code&gt;.zip&lt;/code&gt; composto do seu &lt;code&gt;.aab&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F6y92y22jzvgx7874ihnh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F6y92y22jzvgx7874ihnh.png" alt="Resultado do build"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Crie um app dentro da Play Store Console
&lt;/h3&gt;

&lt;p&gt;Acesse a &lt;a href="https://play.google.com/console/about/" rel="noopener noreferrer"&gt;Play Store Console&lt;/a&gt; e faça a criação do App.&lt;/p&gt;

&lt;p&gt;Esse passo não será detalhado, porque cada tipo de aplicativo segue um fluxo diferente, podendo mudar de acordo com o público, o conteúdo, entre outros aspectos, portanto, siga os passos de acordo com as orientações da Play Store.&lt;/p&gt;

&lt;p&gt;Quando terminar, você estará em um ponto onde será necessário subir o primeiro release do app, nesse ponto, suba o arquivo &lt;code&gt;.aab&lt;/code&gt; gerado no passo anterior, suba as imagens de divulgação e envie seu release para aprovação.&lt;/p&gt;

&lt;p&gt;Essa primeira aprovação pode demorar muitas horas, não tem muito o que fazer, apenas aguardar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Publicação da 2ª release em diante
&lt;/h2&gt;

&lt;p&gt;Legal, agora que seu app está publicado, altere o pipeline para fazer as publicações de forma automática para você.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Inclua autenticação na Play Store
&lt;/h3&gt;

&lt;p&gt;Para fazer a autenticação, você vai precisar de uma &lt;code&gt;Service Account&lt;/code&gt; com acesso para fazer publicações em seu nome na Play Store. Para criar uma siga os passos da &lt;a href="https://developers.google.com/android/management/service-account" rel="noopener noreferrer"&gt;documentação do Android&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Crie a Secret no GhA
&lt;/h3&gt;

&lt;p&gt;Para usar de forma segura sua service account, suba o conteúdo do json em uma secret chamada &lt;code&gt;SERVICE_ACCOUNT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Aproveite que já está nas secrets e adicione uma nova secret chamada PACKAGE_NAME e informe o valor do &lt;code&gt;applicationId&lt;/code&gt; do seu projeto. Essa informação fica no arquivo &lt;code&gt;android/app/build.gradle&lt;/code&gt;. Ex: &lt;code&gt;com.example.myapp&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Altere o script
&lt;/h3&gt;

&lt;p&gt;Adicione os passos a seguir para incluir a publicação na Play Store.&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="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;Create service_account.json&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;createServiceAccount&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 '${{ secrets.SERVICE_ACCOUNT }}' &amp;gt; service_account.json&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 Play Store (Production)&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;deploy&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;r0adkll/upload-google-play@v1.0.12&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;serviceAccountJson&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_account.json&lt;/span&gt;
          &lt;span class="na"&gt;packageName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;secrets.PACKAGE_NAME&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
          &lt;span class="na"&gt;releaseFiles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build/app/outputs/bundle/release/app-release.aab&lt;/span&gt;
          &lt;span class="na"&gt;whatsNewDirectory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;whatsnew/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Acesse a documentação da task &lt;a href="https://github.com/r0adkll/upload-google-play" rel="noopener noreferrer"&gt;r0adkll/upload-google-play&lt;/a&gt; para entender melhor como funciona a configuração do whatsNewDirectory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Não sei vocês, mas eu fico fascinado quando consigo automatizar tarefas massantes como essa. E com todos esses passos realizados, você deve ser capaz de liberar novas versões desse aplicativo de forma automatizada, aproveite o tempo extra para tomar um café, você merece.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Não seja como eu e lembre-se de atualizar o &lt;code&gt;pubspec.yaml&lt;/code&gt; com a versão correta, se tentar submeter duas versões com mesmo número, sua publicação falhará.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Veja que após a primeira publicação, a tarefa que faz upload dos artefatos passa a ser desnecessária, minha recomendação é que você apenas comente ela, para que possa usar em outros aplicativos no futuro.&lt;/p&gt;

</description>
      <category>github</category>
      <category>flutter</category>
      <category>devops</category>
      <category>gha</category>
    </item>
    <item>
      <title>Notificação no Telegram pelo Github Actions</title>
      <dc:creator>Felipe Marques</dc:creator>
      <pubDate>Sun, 31 Oct 2021 12:48:01 +0000</pubDate>
      <link>https://dev.to/felipemsfg/telegram-github-actions-26nj</link>
      <guid>https://dev.to/felipemsfg/telegram-github-actions-26nj</guid>
      <description>&lt;p&gt;🇺🇸 &lt;a href="https://dev.to/felipemsfg/telegram-notification-with-github-actions-69m"&gt;English version&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para receber notificações no Telegram sempre que seu script executar no Github Actions, use o script abaixo:&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="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;Send Telegram Message Ok&lt;/span&gt;
        &lt;span class="s"&gt;uses&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appleboy/telegram-action@master&lt;/span&gt;
        &lt;span class="s"&gt;env&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;GITHUB_CONTEXT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ toJSON(github) }}&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;to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.TELEGRAM_ID }}&lt;/span&gt;
          &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.TELEGRAM_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;markdown&lt;/span&gt;
          &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;*1ª linha da mensagem*&lt;/span&gt;
            &lt;span class="s"&gt;*2ª linha da mensagem*&lt;/span&gt;
            &lt;span class="s"&gt;Applicação: *Preencha como quiser e com quantas linhas quiser* os asteriscos são apenas para deixar o conteúdo em negrito. As linhas abaixo também fazem parte da mensagem e foram escritas para o exemplo.          &lt;/span&gt;
            &lt;span class="s"&gt;Branch: *${{ github.ref }}*&lt;/span&gt;
            &lt;span class="s"&gt;Repository: *${{ github.repository }}*&lt;/span&gt;
            &lt;span class="s"&gt;Owner: *${{ github.repository_owner }}*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se quiser se aprofundar nesse componente, &lt;a href="https://github.com/appleboy/telegram-action"&gt;acesse o github do projeto&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para fazer o uso desse script, você vai precisar de duas informações importantes, o &lt;strong&gt;TELEGRAM_ID&lt;/strong&gt; e o &lt;strong&gt;TELEGRAM_TOKEN&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Para conseguir o TELEGRAM_TOKEN, você precisa criar um bot do telegram, faça isso abrindo uma conversa com o &lt;code&gt;BotFather&lt;/code&gt;. Inicie uma nova mensagem e procure por &lt;code&gt;@botfather&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vtnzps_5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xexc893xpukek2lxjy1n.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vtnzps_5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xexc893xpukek2lxjy1n.jpg" alt="BotFather" width="591" height="1280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Você pode iniciar a conversa enviando um &lt;code&gt;/help&lt;/code&gt; para ver todas as opções possíveis. Mas se quiser pular esse passo, pode enviar &lt;code&gt;/newbot&lt;/code&gt; e siga as instruções. Ao finalizar a criação do bot, você recebe uma mensagem com seu token, como a imagem abaixo:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dHeZeHCF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j70dhdsrcm1ettrbjhf9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dHeZeHCF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j70dhdsrcm1ettrbjhf9.jpg" alt="TELEGRAM_TOKEN" width="591" height="1280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Legal, agora você já tem seu TELEGRAM_TOKEN, no exemplo seria &lt;code&gt;2063069520:AAE7Gcummn9fSp_xLQH7dBGihpzOyWQCm9g&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora, vamos descobrir o seu TELEGRAM_ID. Para isso, basta você procurar o bot &lt;code&gt;@userinfobot&lt;/code&gt; e enviar a mensagem &lt;code&gt;/star&lt;/code&gt; para ele. O retorno da mensagem deve ser algo como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@seu_usuario_no_telegram
Id: 12345678
First: &amp;lt;seu nome&amp;gt;
Last: &amp;lt;seu sobrenome&amp;gt;
Lang: pt-br
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O seu TELEGRAM_ID é o número na segunda linha.&lt;/p&gt;

&lt;p&gt;Nesse ponto você já tem todas as informações para incluir a tarefa de envio de mensagem pelo telegram em todos os seus pipelines.&lt;/p&gt;

&lt;p&gt;Basta incluir as duas variáveis no secrets do seu repositório e usá-las no pipeline.&lt;/p&gt;

</description>
      <category>github</category>
      <category>devops</category>
      <category>gha</category>
    </item>
    <item>
      <title>Como desabilitar o cache no Angular</title>
      <dc:creator>Felipe Marques</dc:creator>
      <pubDate>Sat, 09 Oct 2021 19:01:12 +0000</pubDate>
      <link>https://dev.to/felipemsfg/como-desabilitar-o-cache-no-angular-5bog</link>
      <guid>https://dev.to/felipemsfg/como-desabilitar-o-cache-no-angular-5bog</guid>
      <description>&lt;p&gt;Um dos grandes problemas que enfrentei ao atualizar o frontend de aplicações angular foi o cache. &lt;/p&gt;

&lt;p&gt;Praticamente todos os navegadores mantêm um cache da aplicação no computador do cliente para conseguir carregar a aplicação de forma mais rápida e com menor consumo de dados e isso é excelente. Entretanto, um efeito colateral é que as atualizações podem demorar para serem entregues para o cliente. Como consequência, o cliente pode ficar horas ou dias com uma versão com um bug que já foi corrigido.&lt;/p&gt;

&lt;p&gt;Em sistemas internos de empresas, isso pode resultar em ligações ou tickets constantes para a equipe de suporte técnico, causando uma sobrecarga na equipe. Quando estamos falando de aplicações fornecidas para clientes externos à empresa, pode ser um ponto de frustração e insatisfação com o produto.&lt;/p&gt;

&lt;p&gt;Nesse contexto, pode ser interessante desabilitar o cache das aplicações Angular. Veremos a seguir como fazer isso.&lt;/p&gt;

&lt;h2&gt;
  
  
  Index.html
&lt;/h2&gt;

&lt;p&gt;A primeira opção para evitar o cache dos navegadores é simplesmente indicar ao navegador como ele deve se comportar. Para fazer isso devemos incluir 3 tags &lt;code&gt;meta&lt;/code&gt; no arquivo index.html do projeto.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 html
&amp;lt;meta http-equiv="cache-control" content="no-cache, must-revalidate, post-check=0, pre-check=0"&amp;gt;
&amp;lt;meta http-equiv="expires" content="0"&amp;gt;
&amp;lt;meta http-equiv="pragma" content="no-cache"&amp;gt;


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

&lt;/div&gt;
&lt;p&gt;Com isso, estamos dizendo ao navegador como ele deve tratar o cache, basicamente, dizemos para ele não fazer cache.&lt;/p&gt;
&lt;h2&gt;
  
  
  Angular Interceptor
&lt;/h2&gt;

&lt;p&gt;Uma segunda opção é incluir no cabeçalho das requisições http a instrução para o navegador não fazer cache.&lt;/p&gt;

&lt;p&gt;Se você não sabe como criar um interceptor no angular, veja o artigo a seguir:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="https://medium.com/matheus-bizutti/introdu%C3%A7%C3%A3o-ao-angular-httpinterceptor-1b06a95a0089" class="ltag__link__link" rel="noopener noreferrer"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afill%3A88%3A88%2F1%2ApnbQdfLlfTLXdN_qCOBlRw.jpeg" alt="Matheus Bizutti"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://medium.com/matheus-bizutti/introdu%C3%A7%C3%A3o-ao-angular-httpinterceptor-1b06a95a0089" class="ltag__link__link" rel="noopener noreferrer"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Introdução ao Angular HttpInterceptor | by Matheus Bizutti | Matheus Bizutti | Medium&lt;/h2&gt;
      &lt;h3&gt;Matheus Bizutti ・ &lt;time&gt;Sep 5, 2018&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fmedium-f709f79cf29704f9f4c2a83f950b2964e95007a3e311b77f686915c71574fef2.svg" alt="Medium Logo"&gt;
        Medium
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;p&gt;Agora que você já sabe como criar o interceptor, vamos incluir nosso código no interceptor.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&lt;br&gt;
 ts&lt;br&gt;
import { Injectable } from '@angular/core';&lt;br&gt;
import {&lt;br&gt;
  HttpRequest,&lt;br&gt;
  HttpHandler,&lt;br&gt;
  HttpEvent,&lt;br&gt;
  HttpInterceptor&lt;br&gt;
} from '@angular/common/http';&lt;br&gt;
import { Observable } from 'rxjs';

&lt;p&gt;@Injectable()&lt;br&gt;
export class NoCache.InterceptorInterceptor implements HttpInterceptor {&lt;/p&gt;

&lt;p&gt;constructor() {}&lt;/p&gt;

&lt;p&gt;intercept(request: HttpRequest&amp;lt;unknown&amp;gt;, next: HttpHandler): Observable&amp;lt;HttpEvent&amp;lt;unknown&amp;gt;&amp;gt; {&lt;br&gt;
    // inclua o código da linha abaixo logo no início do método intercept&lt;br&gt;
    request = request.clone({&lt;br&gt;
      setHeaders: {&lt;br&gt;
        "Cache-Control": "no-cache",&lt;br&gt;
        Pragma: "no-cache",&lt;br&gt;
      },&lt;br&gt;
    });&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return next.handle(request);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;br&gt;
}&lt;/p&gt;

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

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  --output-hashing=all&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Uma outra forma de forçar a remoção do cache é compilar a aplicação usando o parâmetro &lt;code&gt;--output-hashing=all&lt;/code&gt;. Assim ao fazer o build com esse parâmetro os arquivos que foram alterados receberão nomes diferentes, quebrando de forma proposital o mecanismo de cache dos navegadores.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ng build --output-hashing=all&lt;/code&gt; ou &lt;code&gt;npm run ng build --output-hashing=all&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Como podemos ver, as três opções são simples de implementar. Quando estamos falando de aplicações empresariais para uso interno, dentro da rede da empresa, não vejo motivos para não usar esse recurso, entretanto, se sua aplicação é utilizada por clientes que a consomem pela internet, use esse recurso com sabedoria, lembre-se que seu cliente pode estar acessando seu produto pelo smartphone com um plano limitado de dados e isso também pode ser um ponto de insatisfação em relação ao seu produto.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
