<?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: Vinícius Beloni</title>
    <description>The latest articles on DEV Community by Vinícius Beloni (@vinibeloni).</description>
    <link>https://dev.to/vinibeloni</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%2F327258%2Fce594bf2-1ec9-43e1-bbeb-1548cc733ee1.jpeg</url>
      <title>DEV Community: Vinícius Beloni</title>
      <link>https://dev.to/vinibeloni</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vinibeloni"/>
    <language>en</language>
    <item>
      <title>Rodando banco de dados no docker!</title>
      <dc:creator>Vinícius Beloni</dc:creator>
      <pubDate>Fri, 03 Jun 2022 03:24:25 +0000</pubDate>
      <link>https://dev.to/vinibeloni/rodando-a-sua-estrutura-de-banco-de-dados-em-um-container-55</link>
      <guid>https://dev.to/vinibeloni/rodando-a-sua-estrutura-de-banco-de-dados-em-um-container-55</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;"Vocês não me escolheram, mas eu os escolhi para irem e darem fruto, fruto que permaneça, a fim de que o Pai lhes conceda o que pedirem em meu nome.&lt;br&gt;
Este é o meu mandamento: amem-se uns aos outros".&lt;br&gt;
"Se o mundo os odeia, tenham em mente que antes odiou a mim."&lt;br&gt;
- João 15.16-18&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Quem nunca precisou subir o próprio banco de dados para testar as alterações feitas numas tabelas? Melhor ainda manter isso versionado e rodando em container. Hoje vou compartilhar com vocês como fazer isso.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sumário
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Criando o projeto&lt;/li&gt;
&lt;li&gt;Dockerfile&lt;/li&gt;
&lt;li&gt;Rodando&lt;/li&gt;
&lt;li&gt;Versionando&lt;/li&gt;
&lt;li&gt;Github Actions&lt;/li&gt;
&lt;li&gt;Fontes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Criando o projeto
&lt;/h3&gt;

&lt;p&gt;Topo&lt;/p&gt;

&lt;p&gt;Vamos iniciar criando um projeto para o DB, esse projeto será responsável por verificar se seu banco está tudo certo. Mas antes devemos instalar o template &lt;a href="https://github.com/rr-wfm/MSBuild.Sdk.SqlProj" rel="noopener noreferrer"&gt;MSBUild.Sdk.Sqlproj&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet new &lt;span class="nt"&gt;--install&lt;/span&gt; MSBuild.Sdk.SqlProj.Templates
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet new sqlproj &lt;span class="nt"&gt;-n&lt;/span&gt; MyDb &lt;span class="nt"&gt;-o&lt;/span&gt; my-db/src &lt;span class="nt"&gt;-s&lt;/span&gt; Sql130
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;my-db
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet sln &lt;span class="nt"&gt;-n&lt;/span&gt; MyDb
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet sln add src &lt;span class="c"&gt;#se exitir um .sqlproj pode adicionar também&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perceba que foi criado um arquivo chamado &lt;code&gt;MyDb.csproj&lt;/code&gt;, ele será responsável por gerenciar o Pre e PostDeploy e "compilar" todo o seu banco de dados. Vamos criar umas tabelas, depois voltaremos para mexer neste arquivo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;mkdir &lt;/span&gt;src/Schemas
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;mkdir &lt;/span&gt;src/Tables

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'CREATE SCHEMA [Bible]'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; src/Schemas/Bible.sql

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'CREATE TABLE [Bible].[Verse](
&amp;gt;&amp;gt;  [VerseId] INT,
&amp;gt;&amp;gt;  [Content] VARCHAR(MAX)
&amp;gt;&amp;gt; )
&amp;gt;&amp;gt; '&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; src/Tables/Verse.sql

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao fazer isso, será concluído o build com sucesso. Ao criar um script incorreto, será lançado o erro no seu terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'CREATE SCHEMA [Pimba] errrrou'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; src/Schemas/Pimba.sql
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet build
EXEC : error SQL46010: Incorrect syntax near errrrou. &lt;span class="o"&gt;[&lt;/span&gt;...]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos criar o script de &lt;code&gt;PostDeploy&lt;/code&gt; e adaptar o arquivo &lt;code&gt;MyDb.csproj&lt;/code&gt; para buscar as &lt;code&gt;Seeds&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;mkdir &lt;/span&gt;src/PostDeploy
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; src/PostDeploy/SeedTables.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;SeedTables.sql&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;PRINT&lt;/span&gt; &lt;span class="s1"&gt;'Merging [Bible].[Verse]'&lt;/span&gt;

&lt;span class="n"&gt;MERGE&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Bible&lt;/span&gt;&lt;span class="p"&gt;].[&lt;/span&gt;&lt;span class="n"&gt;Verse&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;TARGET&lt;/span&gt;
&lt;span class="k"&gt;USING&lt;/span&gt; 
&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Joao 15.16'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Joao 15.17'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Joao 15.18'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;SOURCE&lt;/span&gt; &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;VerseId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;TARGET&lt;/span&gt;&lt;span class="p"&gt;.[&lt;/span&gt;&lt;span class="n"&gt;VerseId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;SOURCE&lt;/span&gt;&lt;span class="p"&gt;.[&lt;/span&gt;&lt;span class="n"&gt;VerseId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;MATCHED&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;TARGET&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt;
    &lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;VerseId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;VerseId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;MATCHED&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt;
    &lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt;
        &lt;span class="n"&gt;TARGET&lt;/span&gt;&lt;span class="p"&gt;.[&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;SOURCE&lt;/span&gt;&lt;span class="p"&gt;.[&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adaptando o &lt;code&gt;MyDb.csproj&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Project&lt;/span&gt; &lt;span class="na"&gt;Sdk=&lt;/span&gt;&lt;span class="s"&gt;"MSBuild.Sdk.SqlProj/2.0.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- [...] --&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Adicione este bloco para utilizar o PostDeploy --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ItemGroup&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Content&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;".\**\*.sql"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

        &lt;span class="c"&gt;&amp;lt;!--Remove all Seed files from the build, but add them as post-deploy https://github.com/rr-wfm/MSBuild.Sdk.SqlProj/issues/103 --&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;Content&lt;/span&gt; &lt;span class="na"&gt;Remove=&lt;/span&gt;&lt;span class="s"&gt;"..\**\Seed\*.sql"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Content&lt;/span&gt; &lt;span class="na"&gt;Remove=&lt;/span&gt;&lt;span class="s"&gt;".\PostDeploy\SeedTables.sql"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;PostDeploy&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;".\PostDeploy\SeedTables.sql"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos testar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet build
&lt;span class="o"&gt;[&lt;/span&gt;...]
Build succeeded.
    0 Warning&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt;
    0 Error&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dockerfile
&lt;/h3&gt;

&lt;p&gt;topo&lt;/p&gt;

&lt;p&gt;Agora com suas tabelas funcionando, vamos rodar em um container:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Dockerfile&lt;/code&gt; (UTF-8):&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;ARG&lt;/span&gt;&lt;span class="s"&gt; DBNAME=MyDb&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; PASSWORD=C0mposed&lt;/span&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-buster-slim&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&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /src&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; src .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet build ./MyDb.csproj &lt;span class="nt"&gt;-c&lt;/span&gt; Release &lt;span class="nt"&gt;-o&lt;/span&gt; /app/build

&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/mssql/server:2017-latest&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;final&lt;/span&gt;

&lt;span class="c"&gt;# Install Unzip&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install &lt;/span&gt;unzip &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Install SQLPackage for Linux and make it executable&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;wget &lt;span class="nt"&gt;-progress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bar:force &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-O&lt;/span&gt; sqlpackage.zip https://go.microsoft.com/fwlink/?linkid&lt;span class="o"&gt;=&lt;/span&gt;2165213 &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; unzip &lt;span class="nt"&gt;-qq&lt;/span&gt; sqlpackage.zip &lt;span class="nt"&gt;-d&lt;/span&gt; /opt/sqlpackage &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;chmod&lt;/span&gt; +x /opt/sqlpackage/sqlpackage

&lt;span class="c"&gt;# Add the DACPAC to the image&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build /app/build/MyDb.dacpac /tmp/db.dacpac&lt;/span&gt;

&lt;span class="c"&gt;# Configure external build arguments to allow configurability.&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; DBNAME&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; PASSWORD&lt;/span&gt;

&lt;span class="c"&gt;# Configure the required environmental variables&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; ACCEPT_EULA=Y&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; SA_PASSWORD=$PASSWORD&lt;/span&gt;

&lt;span class="c"&gt;# Launch SQL Server, confirm startup is complete, deploy the DACPAC, then terminate SQL Server.&lt;/span&gt;
&lt;span class="c"&gt;# See https://stackoverflow.com/a/51589787/488695&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; /opt/mssql/bin/sqlservr &amp;amp; &lt;span class="o"&gt;)&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"Service Broker manager has started"&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; /opt/sqlpackage/sqlpackage /a:Publish /tsn:. /tdn:&lt;span class="nv"&gt;$DBNAME&lt;/span&gt; /tu:sa /tp:&lt;span class="nv"&gt;$SA_PASSWORD&lt;/span&gt; /sf:/tmp/db.dacpac &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; /tmp/db.dacpac &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pkill sqlservr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Resumidamente estamos criando o nome da instância do banco de dados e fazendo o deploy do DACPAC que geramos. Para mais detalhes os links estarão no final do artigo.&lt;/p&gt;

&lt;p&gt;Agora vamos ver se está criando o container corretamente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; docker build &lt;span class="nt"&gt;-t&lt;/span&gt; my-db &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;+] Building 57.5s &lt;span class="o"&gt;(&lt;/span&gt;15/15&lt;span class="o"&gt;)&lt;/span&gt; FINISHED &lt;span class="o"&gt;[&lt;/span&gt;...]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Rodando
&lt;/h3&gt;

&lt;p&gt;topo&lt;/p&gt;

&lt;p&gt;Com tudo preparado, só falta executar o container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; docker run &lt;span class="nt"&gt;--name&lt;/span&gt; testando &lt;span class="nt"&gt;-p&lt;/span&gt; 1433:1433 my-db
SQL Server 2019 will run as non-root by default.
This container is running as user root.
Your master database file is owned by root. &lt;span class="o"&gt;[&lt;/span&gt;...]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para conectar utilize as seguintes informações(SQL Login):&lt;br&gt;
user: sa&lt;br&gt;
pwd: C0mposed&lt;br&gt;
server: localhost, 1433&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq485t8mdsnmmcireycos.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq485t8mdsnmmcireycos.png" alt="Image description" width="272" height="157"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Os próximos passos serão versionar e configurar o Github Actions.&lt;/p&gt;
&lt;h3&gt;
  
  
  Versionando
&lt;/h3&gt;

&lt;p&gt;topo&lt;/p&gt;

&lt;p&gt;Crie o repositório normalmente, eu criarei no Github:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git init
git remote add origin https://github.com/confianodev/my-db-container
git branch -M main
git fetch
git pull origin main
git add .
git commit -m ":tada: a better commit message"
git push --set-upstream origin main
git checkout -b dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa forma, qualquer pessoa que for evoluir as tabelas, views, schemas, indexes, etc. Devem conseguir versionar, compilar e executar o banco de dados.&lt;/p&gt;

&lt;h3&gt;
  
  
  Github Actions
&lt;/h3&gt;

&lt;p&gt;topo&lt;/p&gt;

&lt;p&gt;Agora precisamos automatizar isso para que ninguém fique refém dos testes locais. Lembre-se de criar a secret PACKAGES_TOKEN na organização ou no próprio repositório.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; .github/workflows
&lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; build-homolog.yml
&lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; release-homolog.yml
&lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; rollback-homolog.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conteúdo dos arquivos: &lt;br&gt;
&lt;a href="https://github.com/confianodev/my-db-container/blob/main/.github/workflows" rel="noopener noreferrer"&gt;https://github.com/confianodev/my-db-container/blob/main/.github/workflows&lt;/a&gt;&lt;br&gt;
Lembre-se de trocar o meu usuário(confianodev) pelo seu.&lt;/p&gt;

&lt;p&gt;Feito isso, basta fazer o commit e seu container está pronto para ser compartilhado!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;":wrench: github actions"&lt;/span&gt;
git push &lt;span class="nt"&gt;--set-upstream&lt;/span&gt; origin dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E é isso pessoal, a ideia não é fazer deploy em produção, mas sim facilitar os testes e evitar perder tempo com scripts no banco de homologação. Espero que tenha ajudado.&lt;/p&gt;

&lt;p&gt;Fiquem com a graça e paz do nosso Senhor Jesus Cristo!&lt;/p&gt;

&lt;h3&gt;
  
  
  Fontes
&lt;/h3&gt;

&lt;p&gt;topo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rr-wfm/MSBuild.Sdk.SqlProj" rel="noopener noreferrer"&gt;https://github.com/rr-wfm/MSBuild.Sdk.SqlProj&lt;/a&gt;&lt;br&gt;
&lt;a href="https://itnext.io/how-to-build-and-run-a-sql-container-using-a-dacpac-file-c7b0d30f6255" rel="noopener noreferrer"&gt;https://itnext.io/how-to-build-and-run-a-sql-container-using-a-dacpac-file-c7b0d30f6255&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>github</category>
      <category>database</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>[Avançado] Criando templates customizados em C#</title>
      <dc:creator>Vinícius Beloni</dc:creator>
      <pubDate>Tue, 10 May 2022 15:53:52 +0000</pubDate>
      <link>https://dev.to/vinibeloni/avancado-criando-templates-customizados-em-c-8jc</link>
      <guid>https://dev.to/vinibeloni/avancado-criando-templates-customizados-em-c-8jc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Portanto, se alguém está em Cristo, é nova criação. As coisas antigas já passaram; eis que surgiram coisas novas!&lt;br&gt;
2 Coríntios 5.17&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Sumário:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Estrutura final&lt;/li&gt;
&lt;li&gt;Preparando a solução&lt;/li&gt;
&lt;li&gt;Criando repositório remoto&lt;/li&gt;
&lt;li&gt;Github Secrets&lt;/li&gt;
&lt;li&gt;Configurando o pacote&lt;/li&gt;
&lt;li&gt;Publicando o template&lt;/li&gt;
&lt;li&gt;Fontes&lt;/li&gt;
&lt;li&gt;Agradecimentos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No &lt;a href="https://dev.to/vinibeloni/simples-criando-templates-customizados-em-c-2d2j"&gt;tutorial anterior&lt;/a&gt; vimos juntos como criar um template de um jeito bem simples, agora porém, vamos escalar a simplicidade e criar uma solução completa de forma replicável, onde teremos publicação automática utilizando Github Actions, Nuget registry e muito mais!&lt;/p&gt;

&lt;h3&gt;
  
  
  Estrutura final
&lt;/h3&gt;

&lt;p&gt;voltar ao topo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;PS C:/repos/my-templates&amp;gt; tree /f
│   .gitignore
│   TemplatePack.csproj
│
├───.github
│   └───workflows
│           publish.yml
│
└───templates
    └───customapi
        │   .dockerignore
        │   .editorconfig
        │   .gitattributes
        │   .gitignore
        │   Dockerfile
        │   MyProject.sln
        │
        ├───.template.config
        │       template.json
        │
        ├───src
        │   │   appsettings.Development.json
        │   │   appsettings.json
        │   │   MyProject.csproj
        │   │   Program.cs
        │   │   WeatherForecast.cs
        │   │
        │   ├───Controllers
        │   │       WeatherForecastController.cs
        │   │
        │   └───Properties
        │           launchSettings.json
        │
        └───tests
                MyProject.Tests.csproj
                UnitTest1.cs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos começar criando um diretório para hospedar os templates, pois com esse tutorial será possível ter vários em um único pacote. Então para a API vamos criar dois projetos, um para o código de produção(src) e outro para testes de unidade(tests) mas fique a vontade para seguir o que funciona pra você, também vamos criar uma &lt;em&gt;solution&lt;/em&gt; e outros arquivos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparando a solução
&lt;/h2&gt;

&lt;p&gt;voltar ao topo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;mkdir &lt;/span&gt;templates/customapi
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;templates/customapi
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet new webapi &lt;span class="nt"&gt;--no-https&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; MyProject &lt;span class="nt"&gt;-o&lt;/span&gt; src
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet new xunit &lt;span class="nt"&gt;-n&lt;/span&gt; MyProject.Tests &lt;span class="nt"&gt;-o&lt;/span&gt; tests
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet new sln &lt;span class="nt"&gt;-n&lt;/span&gt; MyProject
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet add ./tests/ reference ./src
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet sln add ./src/ ./tests/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos criar o restante dos arquivos (Encoding: UTF-8):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Dockerfile
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .editorconfig
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .gitignore
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .dockerignore
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .gitattributes
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;mkdir&lt;/span&gt; .template.config
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .template.config/template.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;.gitignore&lt;/code&gt;: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/github/gitignore/blob/main/VisualStudio.gitignore"&gt;https://github.com/github/gitignore/blob/main/VisualStudio.gitignore&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Dockerfile&lt;/code&gt;:&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="s"&gt; mcr.microsoft.com/dotnet/sdk:6.0 AS build&lt;/span&gt;

&lt;span class="c"&gt;# remover se não usar .editorconfig&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PATH="$PATH:/root/.dotnet/tools"&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet tool &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; dotnet-format

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /src&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 restore
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet build &lt;span class="nt"&gt;-c&lt;/span&gt; Release &lt;span class="nt"&gt;--no-restore&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; Release &lt;span class="nt"&gt;--no-build&lt;/span&gt;

&lt;span class="c"&gt;# remover se não usar .editorconfig&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet format &lt;span class="nt"&gt;--verify-no-changes&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet publish &lt;span class="s2"&gt;"src/MyProject.csproj"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; Release &lt;span class="nt"&gt;--no-build&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /app/publish

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; mcr.microsoft.com/dotnet/aspnet:6.0 AS final&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 /app/publish .&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["dotnet", "MyProject.dll"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;.dockerignore&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;.gitattributes&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* text=auto
*.cs text eol=crlf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;.editorconfig&lt;/code&gt; (Opcional):&lt;br&gt;
&lt;a href="https://docs.microsoft.com/pt-br/dotnet/fundamentals/code-analysis/code-style-rule-options"&gt;Padrão do .NET&lt;/a&gt;&lt;br&gt;
&lt;a href="https://gist.github.com/vinibeloni/46dc1601f6139c0523faab1276e52778"&gt;O padrão que eu utilizo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para formatar seu código instale o &lt;a href="https://github.com/dotnet/format"&gt;dotnet format&lt;/a&gt; e execute o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet tool &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; dotnet-format
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet format
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;template.json&lt;/code&gt;: &lt;br&gt;
Podemos seguir o mesmo do &lt;a href="https://dev.to/vinibeloni/simples-criando-templates-customizados-em-c-2d2j"&gt;tutorial anterior&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"$schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://json.schemastore.org/template"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@confianodev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"identity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MyCustomWebApi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My Custom Web Api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"shortName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"customapi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"preferNameDirectory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"sourceName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MyProject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"classifications"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Web API"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"API"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"language"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"C#"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"project"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Criando repositório remoto
&lt;/h3&gt;

&lt;p&gt;voltar ao topo&lt;/p&gt;

&lt;p&gt;Agora começa as diferenças, no caso como estamos trabalhando com multiplos projetos e até templates, vamos criar um arquivo &lt;code&gt;.csproj&lt;/code&gt; na raiz da nossa solução. Este arquivo terá várias informações para empacotar todos os templates e publicá-los posteriormente, mas antes vamos criar um repositório remoto.&lt;/p&gt;

&lt;p&gt;Vá até o &lt;a href="https://github.com/new"&gt;Github&lt;/a&gt;, crie um novo repositório vazio e siga este passo-a-passo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; ../..
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git init
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git add &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"initial template files"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git branch &lt;span class="nt"&gt;-M&lt;/span&gt; main
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git remote add origin https://github.com/SEU-USER/seurepo.git
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Github Secrets
&lt;/h3&gt;

&lt;p&gt;voltar ao topo&lt;/p&gt;

&lt;p&gt;Para publicar o pacote devemos criar um Token, basta criar um &lt;a href="https://github.com/settings/tokens"&gt;Personal Access Token&lt;/a&gt; com permissões de &lt;code&gt;write:packages&lt;/code&gt; e copiar o conteúdo, depois vá para a aba &lt;br&gt;
&lt;code&gt;Setting &amp;gt; Secrets &amp;gt; Actions&lt;/code&gt; do repositório que criamos e clique em "New repository secret", ao pedir um &lt;em&gt;Name&lt;/em&gt; coloque como "PACKAGES_TOKEN" (válido para este tutorial, mas pode colocar o nome que quiser) e no &lt;em&gt;Value&lt;/em&gt; cole o Token que você acabou de criar.&lt;/p&gt;
&lt;h3&gt;
  
  
  Configurando o pacote
&lt;/h3&gt;

&lt;p&gt;voltar ao topo&lt;/p&gt;

&lt;p&gt;Com tudo isso pronto, vamos criar nosso arquivo de template que será utilizado pelo comando &lt;code&gt;dotnet pack&lt;/code&gt;. Lembrando que o campo &lt;code&gt;&amp;lt;RepositoryUrl&amp;gt;&lt;/code&gt; precisa ser preenchido corretamente com o nome do repositório que acabamos de criar, caso contrário teremos problemas ao publicar o nosso pacote:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; TemplatePack.csproj
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;TemplatePack.csproj&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Project&lt;/span&gt; &lt;span class="na"&gt;Sdk=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.NET.Sdk"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageType&amp;gt;&lt;/span&gt;Template&lt;span class="nt"&gt;&amp;lt;/PackageType&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageVersion&amp;gt;&lt;/span&gt;1.0.0&lt;span class="nt"&gt;&amp;lt;/PackageVersion&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageId&amp;gt;&lt;/span&gt;my.templates&lt;span class="nt"&gt;&amp;lt;/PackageId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Title&amp;gt;&lt;/span&gt;My Templates&lt;span class="nt"&gt;&amp;lt;/Title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Authors&amp;gt;&lt;/span&gt;@confianodev&lt;span class="nt"&gt;&amp;lt;/Authors&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;RepositoryUrl&amp;gt;&lt;/span&gt;ALÔ, GALERA DE COWBOY&lt;span class="nt"&gt;&amp;lt;/RepositoryUrl&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;RepositoryType&amp;gt;&lt;/span&gt;git&lt;span class="nt"&gt;&amp;lt;/RepositoryType&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Description&amp;gt;&lt;/span&gt;Templates utilizados para criar meus projetos HAHA&lt;span class="nt"&gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageTags&amp;gt;&lt;/span&gt;dotnet-new;templates;&lt;span class="nt"&gt;&amp;lt;/PackageTags&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;TargetFramework&amp;gt;&lt;/span&gt;net6.0&lt;span class="nt"&gt;&amp;lt;/TargetFramework&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;IncludeContentInPack&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/IncludeContentInPack&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;IncludeBuildOutput&amp;gt;&lt;/span&gt;false&lt;span class="nt"&gt;&amp;lt;/IncludeBuildOutput&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ContentTargetFolders&amp;gt;&lt;/span&gt;content&lt;span class="nt"&gt;&amp;lt;/ContentTargetFolders&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;NoDefaultExcludes&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/NoDefaultExcludes&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;NoWarn&amp;gt;&lt;/span&gt;$(NoWarn);NU5128&lt;span class="nt"&gt;&amp;lt;/NoWarn&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;ItemGroup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Content&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"templates\**\*"&lt;/span&gt; &lt;span class="na"&gt;Exclude=&lt;/span&gt;&lt;span class="s"&gt;"templates\**\bin\**;templates\**\obj\**"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Compile&lt;/span&gt; &lt;span class="na"&gt;Remove=&lt;/span&gt;&lt;span class="s"&gt;"**\*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para mais informações, acesse &lt;a href="https://docs.microsoft.com/pt-br/dotnet/core/tutorials/cli-templates-create-template-package"&gt;este link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Customize do jeito que for melhor, nesse momento poderiamos aplicar nossos padrões, criar classes de apoio(repositórios, métodos de extensão, configurações de log, startup, etc). Após tudo feito, podemos testar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet &lt;span class="nb"&gt;test &lt;/span&gt;templates/customapi/tests
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet run &lt;span class="nt"&gt;--project&lt;/span&gt; templates/customapi/src
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos empacotar tudo e testar nosso novo template, pois o próximo passo será jogar isso para o Nuget:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet pack
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet new &lt;span class="nt"&gt;-i&lt;/span&gt; ./bin/Debug/my.templates.1.0.0.nupkg
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet new customapi &lt;span class="nt"&gt;-n&lt;/span&gt; Pimba &lt;span class="nt"&gt;-o&lt;/span&gt; sample
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; /sample
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet new &lt;span class="nt"&gt;--uninstall&lt;/span&gt; my.templates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Excelente! Template testado e funcional, agora vamos automatizar a publicação de novas versões e publicar o nosso pacote Nuget.&lt;/p&gt;

&lt;h3&gt;
  
  
  Publicando o template
&lt;/h3&gt;

&lt;p&gt;voltar ao topo&lt;/p&gt;

&lt;p&gt;Vamos configurar o Github Actions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;mkdir&lt;/span&gt; .github/workflows
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .github/workflows/publish.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;publish.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

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

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

  &lt;span class="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@v2&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;Setup .NET &lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt; &lt;span class="c1"&gt;# atualize se for necessário&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-dotnet@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;dotnet-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;6.0.202&lt;/span&gt; &lt;span class="c1"&gt;# atualize se for necessário&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;Generate package&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;dotnet pack -c Debug -o out --include-symbols --include-source --verbosity Detailed&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;Publish NuGet&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;cd out&lt;/span&gt;
          &lt;span class="s"&gt;dotnet nuget push *.nupkg --api-key ${{ secrets.PACKAGES_TOKEN }} --source https://nuget.pkg.github.com/SEU-USER/index.json --skip-duplicate&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Faça o commit das alterações e vamos ver o resultado do Github Actions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; copy ./templates/customapi/.gitignore .gitignore
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git add &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"add publish action"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se tudo deu certo, na aba &lt;em&gt;Actions&lt;/em&gt; do seu reposítorio o pacote estará sendo preparado e pronto para ser utilizado. Mas agora que seu pacote está disponível, precisamos adicioná-lo localmente:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Observação&lt;/em&gt;: Vou utilizar o Token que criei acima, mas o &lt;em&gt;ideal&lt;/em&gt; para utilizar pacotes privados é criar um outro Token somente com o acesso &lt;code&gt;read:packages&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet nuget add &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="s2"&gt;"https://nuget.pkg.github.com/SEU-USER/index.json"&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; Github &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"SEU-USER"&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"TOKEN-QUE-CRIAMOS"&lt;/span&gt; &lt;span class="nt"&gt;--store-password-in-clear-text&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet new &lt;span class="nt"&gt;-i&lt;/span&gt; my-templates
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet new customapi &lt;span class="nt"&gt;-n&lt;/span&gt; Opa &lt;span class="nt"&gt;-o&lt;/span&gt; sample
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Saída do meu terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;PS C:&lt;span class="se"&gt;\r&lt;/span&gt;epos&lt;span class="se"&gt;\c&lt;/span&gt;riando-template&amp;gt; dotnet new &lt;span class="nt"&gt;-i&lt;/span&gt; power.templates
The following template packages will be installed:
   power.templates

Failed to download package &lt;span class="s1"&gt;'power.templates.1.0.0'&lt;/span&gt; from &lt;span class="s1"&gt;'https://nuget.pkg.github.com/confianodev/download/power.templates/1.0.0/power.templates.1.0.0.nupkg'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
The HTTP request to &lt;span class="s1"&gt;'GET https://nuget.pkg.github.com/confianodev/download/power.templates/1.0.0/power.templates.1.0.0.nupkg'&lt;/span&gt; has timed out after 100000ms.
Warning: Failed to scan C:&lt;span class="se"&gt;\r&lt;/span&gt;epos&lt;span class="se"&gt;\c&lt;/span&gt;riando-template&lt;span class="se"&gt;\s&lt;/span&gt;rc.
Details: Template package location C:&lt;span class="se"&gt;\r&lt;/span&gt;epos&lt;span class="se"&gt;\c&lt;/span&gt;riando-template&lt;span class="se"&gt;\s&lt;/span&gt;rc is not supported, or doesn&lt;span class="s1"&gt;'t exist.
Success: power.templates::1.0.0 installed the following templates:
Template Name  Short Name  Language  Tags       
-------------  ----------  --------  -----------
My Web Api     customapi   [C#]      Web API/API
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para adicionar novos templates, basta criar novas pastas e projetos dentro da pasta &lt;code&gt;templates&lt;/code&gt; assim como fizemos para a &lt;code&gt;templates/customapi&lt;/code&gt;:&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;mkdir &lt;/span&gt;templates/customrobot
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;templates/customrobot
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet new console &lt;span class="nt"&gt;-n&lt;/span&gt; MyProject &lt;span class="nt"&gt;-o&lt;/span&gt; src
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E é isso! Fico muito feliz de ter compartilhado com você esta experiência. Espero que consiga aumentar a sua produtividade e das pessoas que trabalham com você. Qualquer dúvida por favor deixem nos comentários!&lt;/p&gt;

&lt;p&gt;Até a próxima, se assim o Senhor Pai nos permitir, Abraços!&lt;/p&gt;

&lt;h3&gt;
  
  
  Fontes
&lt;/h3&gt;

&lt;p&gt;voltar ao topo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/pt-br/dotnet/core/tutorials/cli-templates-create-template-package"&gt;Como criar um pacote modelo&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.github.com/pt/packages/working-with-a-github-packages-registry/working-with-the-nuget-registry"&gt;Working with the Nuget registry&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.microsoft.com/pt-br/nuget/nuget-org/publish-a-package"&gt;https://docs.microsoft.com/pt-br/nuget/nuget-org/publish-a-package&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Agradecimentos
&lt;/h3&gt;

&lt;p&gt;voltar ao topo&lt;/p&gt;

&lt;p&gt;Agradecimentos especiais ao &lt;a href="https://github.com/SammyROCK"&gt;SammyROCK&lt;/a&gt;, pois trabalhando com ele aprendi muita coisa, principalmente sobre Docker, Github Actions, Secrets, Nuget Registry, etc. Obrigado!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>[Simples] Criando templates customizados em C#</title>
      <dc:creator>Vinícius Beloni</dc:creator>
      <pubDate>Sat, 07 May 2022 17:58:25 +0000</pubDate>
      <link>https://dev.to/vinibeloni/simples-criando-templates-customizados-em-c-2d2j</link>
      <guid>https://dev.to/vinibeloni/simples-criando-templates-customizados-em-c-2d2j</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;"Sejam bondosos e compassivos uns para com os outros, perdoando-se mutualmente, assim como Deus os perdoou em Cristo."&lt;br&gt;
Efésios 4.32&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Provavelmente você já viu ou utilizou o comando &lt;code&gt;dotnet new&lt;/code&gt; para criar projetos usando o &lt;del&gt;novo&lt;/del&gt; .NET, então vou te mostrar como criar seu próprio template customizado!&lt;/p&gt;

&lt;p&gt;Pré-requisitos (para este tutorial):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/pt-br/dotnet/machine-learning/how-to-guides/install-ml-net-cli"&gt;dotnet CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/"&gt;VS Code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vou criar o template de um projeto Web API, mas podemos criar templates de arquivos ou até estruturas completas com &lt;code&gt;Dockerfile&lt;/code&gt;, &lt;code&gt;.editorconfig&lt;/code&gt;, &lt;code&gt;.sln&lt;/code&gt;, estruturas de pastas e etc, tudo depende da sua necessidade (ou criatividade). Mas para este tutorial faremos da forma mais simples e útil para este momento, então vamos prosseguir.&lt;/p&gt;

&lt;p&gt;Com o terminal do VSCode aberto, vamos criar um projeto do tipo Web API, customizar e remover o que for desnecessário.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet new webapi &lt;span class="nt"&gt;--no-https&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; MyProject &lt;span class="nt"&gt;-o&lt;/span&gt; src
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ri src/WeatherForecast.cs
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ren src/Controllers/WeatherForecastController.cs MyController.cs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Faremos algumas alterações no arquivo &lt;code&gt;MyController.cs&lt;/code&gt; (caso seja iniciante não copie o código, mas escreva linha por linha).&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;Microsoft.AspNetCore.Mvc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// MyProject será substituido pelo nome do projeto ao criar o template&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;MyProject.Controllers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ApiController&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[controller]"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="c1"&gt;// WeatherForecast foi renomeado para My&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;MyController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ControllerBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyController&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;MyController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyController&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&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="nf"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Olá Mundo"&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="nf"&gt;HttpPost&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;void&lt;/span&gt; &lt;span class="nf"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;FromBody&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"received &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&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;Agora vamos rodar para ver se está tudo certo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet run &lt;span class="nt"&gt;--project&lt;/span&gt; src
Building...
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5172
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:&lt;span class="se"&gt;\r&lt;/span&gt;epos&lt;span class="se"&gt;\c&lt;/span&gt;riando-template&lt;span class="se"&gt;\s&lt;/span&gt;rc&lt;span class="se"&gt;\&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eu utilizo uma extensão chamada &lt;a href="https://marketplace.visualstudio.com/items?itemName=humao.rest-client"&gt;REST Client&lt;/a&gt; para fazer as requisições usando o próprio VSCode para testar coisas mais rapidamente, mas você pode utilizar o &lt;a href="https://www.postman.com/"&gt;Postman&lt;/a&gt; se preferir ou o próprio navegador no caso do método GET. Para não confundir ninguém vou mostrar o resultado do meu terminal ao fazer as requisições.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;info: MyProject.Controllers.MyController[0]
      Hello World
info: MyProject.Controllers.MyController[0]
      received &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"confia"&lt;/span&gt;: &lt;span class="s2"&gt;"no Pai"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora com a nossa Web API customizada, vamos configurar o nosso template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;mkdir&lt;/span&gt; ./src/.template.config
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ./src/.template.config/template.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conteúdo do arquivo &lt;code&gt;template.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"$schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://json.schemastore.org/template"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@confianodev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"identity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My Web Api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My Web Api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"shortName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"myapi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"preferNameDirectory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"sourceName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MyProject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"classifications"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Web API"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"API"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"language"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"C#"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"project"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vou dar uma breve explicação de alguns desses campos, lembrando que podemos adaptar essas informações:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;author&lt;/strong&gt; - Nome de quem tem a propriedade intelectual deste template(você, a empresa, uma organização).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;shortName&lt;/strong&gt; - O nome que será utilizado no comando, exemplo: &lt;code&gt;dotnet new myapi&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;preferNameDirectory&lt;/strong&gt; - Caso seja &lt;code&gt;true&lt;/code&gt; será gerado o projeto dentro de uma pasta com o nome informado(&lt;code&gt;dotnet new myapi -n EsseNome&lt;/code&gt;) caso seja &lt;code&gt;false&lt;/code&gt; não cria pasta nenhuma.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;sourceName&lt;/strong&gt; - Muito importante pois é a palavra-chave que vai substituir arquivos, namespace, textos, etc, ao criar um novo projeto usando o seu template (&lt;code&gt;dotnet new myapi -n PalavraChave&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tags&lt;/strong&gt; - Utilizado para informar qual o tipo do template e quais linguagens são suportadas(podemos criar em F# também)&lt;/p&gt;

&lt;p&gt;Para mais informações pode acessar este &lt;a href="https://github.com/dotnet/templating/wiki/"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Finalmente, vamos instalar nosso template, criar um projeto e testá-lo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet new &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet new myapi &lt;span class="nt"&gt;-n&lt;/span&gt; Oloko &lt;span class="nt"&gt;-o&lt;/span&gt; sample
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet run &lt;span class="nt"&gt;--project&lt;/span&gt; sample/
Building...
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5172
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:&lt;span class="se"&gt;\r&lt;/span&gt;epos&lt;span class="se"&gt;\c&lt;/span&gt;riando-template&lt;span class="se"&gt;\s&lt;/span&gt;ample&lt;span class="se"&gt;\&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E está pronto o nosso template. Lembrando que a ideia do template é facilitar a criação de novos projetos e novos arquivos, então crie da maneira que for mais útil para o seu dia-a-dia.&lt;/p&gt;

&lt;p&gt;Caso queria desinstalar basta utilizar 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;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dotnet new &lt;span class="nt"&gt;--uninstall&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claro que este é o jeito mais simples de fazer um template, no próximo Post vou mostrar como criar uma solução completa, com dois projetos e uma solução, com Dockerfile, padronização de código e etc, utilizando o github actions para publicar como pacote Nuget.&lt;/p&gt;

&lt;p&gt;Fico muito agradecido de ter compartilhado este conhecimento com você, se tiver alguma dúvida deixe nos comentários.&lt;/p&gt;

&lt;p&gt;Acesse meu canal no YouTube &lt;a href="https://www.youtube.com/channel/UCtzrdserH-SqGFPKhj72UUg"&gt;clicando aqui&lt;/a&gt;&lt;br&gt;
E caso queria ir para o post mais avançado, &lt;a href="https://dev.to/vinibeloni/avancado-criando-templates-customizados-em-c-8jc"&gt;clique aqui&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Abraços e até a próxima!&lt;/p&gt;

&lt;p&gt;Fontes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=nnr9yeYtr6I"&gt;Donovan Brown: Custom Templates for dotnet new&lt;/a&gt;&lt;br&gt;
&lt;a href="https://devblogs.microsoft.com/dotnet/how-to-create-your-own-templates-for-dotnet-new/"&gt;How to create your own templates&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/dotnet/templating/wiki/"&gt;Templating Wiki&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>template</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
