<?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: Raul Andrade</title>
    <description>The latest articles on DEV Community by Raul Andrade (@andraderaul).</description>
    <link>https://dev.to/andraderaul</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%2F845977%2F9894d6ad-6f2a-4809-94b4-b84e537a0d29.jpeg</url>
      <title>DEV Community: Raul Andrade</title>
      <link>https://dev.to/andraderaul</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andraderaul"/>
    <language>en</language>
    <item>
      <title>Como construí um ASCII Art Converter cyberpunk usando apenas prompts</title>
      <dc:creator>Raul Andrade</dc:creator>
      <pubDate>Mon, 04 May 2026 13:46:32 +0000</pubDate>
      <link>https://dev.to/andraderaul/como-construi-um-ascii-art-converter-cyberpunk-usando-apenas-prompts-k5</link>
      <guid>https://dev.to/andraderaul/como-construi-um-ascii-art-converter-cyberpunk-usando-apenas-prompts-k5</guid>
      <description>&lt;p&gt;Nos últimos meses me afundei no universo cyberpunk. Li &lt;em&gt;Neuromancer&lt;/em&gt;. Ainda estou no meio de &lt;em&gt;Count Zero&lt;/em&gt;. Zerei &lt;em&gt;Cyberpunk 2077&lt;/em&gt;. Revi &lt;em&gt;Akira&lt;/em&gt;, &lt;em&gt;Ghost in the Shell&lt;/em&gt; e &lt;em&gt;Cyberpunk Edgerunners&lt;/em&gt;. Tem algo nessa estética (neon, interfaces cruas, informação como matéria-prima) que não sai da cabeça.&lt;/p&gt;

&lt;p&gt;Foi nesse estado que me deparei com um vídeo no Instagram de uma garota mostrando uma aplicação que convertia a câmera ao vivo em arte ASCII em tempo real, com análise de IA integrada. Fui no link. Estava offline.&lt;/p&gt;

&lt;p&gt;Dois pensamentos na hora: &lt;em&gt;eu consigo construir isso&lt;/em&gt; e &lt;em&gt;vou deixar qualquer pessoa usar com a própria key de IA&lt;/em&gt;. E um terceiro: &lt;em&gt;vou construir sem escrever uma linha de código manualmente&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por que essa regra
&lt;/h2&gt;

&lt;p&gt;Eu já usava Cursor faz um tempo, inclusive no modo agente. Mas por ser uma IDE, ficava tentado a meter a mão no código direto. Quando assinei o Claude Code, quis testar o que acontece quando você remove essa tentação completamente e força a delegação de verdade.&lt;/p&gt;

&lt;p&gt;A regra foi simples: tudo via prompt. Sem abrir arquivos pra editar. As únicas exceções foram mudanças de uma linha, &lt;code&gt;'upload'&lt;/code&gt; virou &lt;code&gt;'upload' as const&lt;/code&gt;, um ajuste de cor no CSS.&lt;/p&gt;

&lt;h2&gt;
  
  
  O código pode ser gerado, a direção não
&lt;/h2&gt;

&lt;p&gt;Antes de qualquer prompt, a feature precisa estar estruturada na cabeça. Quais são as entradas, quais são as saídas, o que muda no estado, o que não muda. No fim, isso é muito próximo do que bons desenvolvedores já fazem antes de começar a escrever código. A diferença é que, quando você deixa de implementar diretamente, a clareza do pensamento vira o principal mecanismo de controle durante o processo.&lt;/p&gt;

&lt;p&gt;O mesmo vale pra contexto. Ter decisões arquiteturais documentadas e um glossário claro do domínio ajuda muito durante o processo. Sem isso, fica bem mais difícil manter consistência conforme o projeto cresce. O Claude não lembra o raciocínio da semana passada. Eu mantive um &lt;code&gt;CONTEXT.md&lt;/code&gt; com os termos do domínio e um &lt;code&gt;docs/adr/&lt;/code&gt; com as decisões importantes: por que o canvas oculto existe separado do canvas visível, por que o loop de webcam roda na main thread. Sem isso, cada prompt novo começa do zero.&lt;/p&gt;

&lt;p&gt;Skills funcionam como atalhos de contexto. Em vez de descrever o que você quer numa revisão de segurança toda vez, você invoca &lt;code&gt;/security-review&lt;/code&gt; e o agente já sabe o que checar. Eu usei as skills do Matt Pocock como base e adaptei algumas pro meu fluxo.&lt;/p&gt;

&lt;p&gt;Quebrar o problema em partes menores continuou sendo uma das coisas mais importantes durante o projeto. Quanto menor e mais bem definido era o escopo de cada etapa, menos a IA se perdia, mais previsível o resultado ficava e mais fácil era iterar em cima do que tinha sido gerado.&lt;/p&gt;

&lt;h2&gt;
  
  
  A faca de dois gumes
&lt;/h2&gt;

&lt;p&gt;A velocidade de geração de código é real. E é exatamente onde o negócio pode dar errado.&lt;/p&gt;

&lt;p&gt;Em um ponto do projeto, o Claude tinha construído o componente de upload com &lt;code&gt;useState&lt;/code&gt; espalhado por todo lado, com dependências claras entre eles. Olhei pra aquilo e o padrão estava errado: precisava de &lt;code&gt;useReducer&lt;/code&gt;. Não abri o arquivo. Mandei um prompt pedindo pra extrair a lógica pra um hook com &lt;code&gt;useReducer&lt;/code&gt;. Ficou limpo.&lt;/p&gt;

&lt;p&gt;Em outro momento, o Claude entrou num loop tentando resolver um problema de testes. Cada tentativa criava um problema novo. Parei, reverti tudo, e reescrevi o prompt do zero com o contexto de como os testes são estruturados nessa aplicação. Resolveu na primeira tentativa.&lt;/p&gt;

&lt;p&gt;A velocidade não substitui o julgamento. E isso ficou claro pra mim nesses dois momentos. O modelo escreve rápido e errado da mesma forma que escreve rápido e certo, e sem o julgamento de quem conhece o domínio, você só acumula dívida técnica mais rápido do que antes.&lt;/p&gt;

&lt;h2&gt;
  
  
  O resultado
&lt;/h2&gt;

&lt;p&gt;O &lt;a href="https://github.com/andraderaul/ascii-art-converter" rel="noopener noreferrer"&gt;ASCII Art Converter&lt;/a&gt; tem webcam ao vivo, análise de IA com Anthropic, OpenAI ou Gemini, export em PNG e TXT, e um design system cyberpunk que ficou exatamente do jeito que eu queria e foi estranhamente satisfatório ver tudo montado sem ter aberto um arquivo pra editar. Zero features escritas com as mãos.&lt;/p&gt;

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

&lt;p&gt;Se você já tem o hábito de pensar antes de codar, documentar decisões e quebrar trabalho em partes pequenas, você tem o pré-requisito pra tentar isso. Não precisa de um projeto grande, um side project já é suficiente pra entender onde essa abordagem funciona e onde ela ainda patina.&lt;/p&gt;

&lt;p&gt;Se ficou curioso sobre como organizei o projeto, alguma decisão específica ou quer ver como os prompts ficaram, deixa um comentário.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/andraderaul/ascii-art-converter" rel="noopener noreferrer"&gt;Repo&lt;/a&gt;&lt;br&gt;
&lt;a href="https://ascii-art-converter-tawny.vercel.app/" rel="noopener noreferrer"&gt;Demo&lt;/a&gt;&lt;br&gt;
&lt;a href="https://claude.ai/code" rel="noopener noreferrer"&gt;Claude Code&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/mattpocock/skills" rel="noopener noreferrer"&gt;Skills for Real Engineers — Matt Pocock&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.instagram.com/p/DXKDEZxTPDz/" rel="noopener noreferrer"&gt;Vídeo que inspirou o projeto&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>productivity</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Como automatizar o processo de versionamento de um projeto em Javascript</title>
      <dc:creator>Raul Andrade</dc:creator>
      <pubDate>Sat, 11 Jun 2022 16:00:39 +0000</pubDate>
      <link>https://dev.to/andraderaul/como-automatizar-o-processo-de-versionamento-de-um-projeto-em-javascript-1kc9</link>
      <guid>https://dev.to/andraderaul/como-automatizar-o-processo-de-versionamento-de-um-projeto-em-javascript-1kc9</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Como desenvolvedores, amamos automatizar tarefas rotineiras. Nesta publicação demonstrarei a automação do fluxo de release utilizando a biblioteca &lt;strong&gt;semantic-release&lt;/strong&gt;. Esta library permite automatizar todo o oprocesso de geração de release; Determinando o número da próxima versão, criando a nova tag, gerando as novas release notes e a publicação do pacote no NPM, caso seja necessário.&lt;/p&gt;

&lt;p&gt;Para tudo isso funcionar, a biblioteca faz uso das mensagens de commits para determinar o número da próxima versão, o Changelog e a publicação. Por padrão o &lt;strong&gt;semantic-release&lt;/strong&gt; utiliza a especificação de mensagens de commits do Angular o &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/" rel="noopener noreferrer"&gt;Conventional Commits&lt;/a&gt; e a convenção &lt;a href="https://semver.org/" rel="noopener noreferrer"&gt;semver&lt;/a&gt; para o número de versão.&lt;/p&gt;

&lt;p&gt;Resumindo o SemVer nos diz como devem ser os números de nossas versões, como por exemplo: &lt;code&gt;MAJOR.MINOR.PATCH&lt;/code&gt;. Já o Conventional Commits nos diz como devem ser nossos commits, para que o de/para do commit pro SemVer seja feito de forma automática.&lt;/p&gt;

&lt;p&gt;Abaixo mostrarei uma imagem desse de/para:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffle3zxztn9nv43o2izhz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffle3zxztn9nv43o2izhz.png" alt="De/para do SemVer para Tag de versionamento" width="334" height="633"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No CI o &lt;strong&gt;semantic-release&lt;/strong&gt; deve ser executado após o build ser feito com sucesso no branch de release, por exemplo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como funciona
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;semantic-release&lt;/strong&gt; verifica os commits de um branch entre a última tag gerada até o último commit deste branch, para então acionar a geração de uma nova tag. Em seguida ele cria ou atualiza o arquivo de Changelog com base nos commits entre as duas tags.&lt;/p&gt;

&lt;p&gt;Ná prática fica da seguinte forma, como é mostrado na imagem a seguir: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxqcqhhews840a2fsyt7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxqcqhhews840a2fsyt7.png" alt="Na imagem mostra uma linha do tempo de commits" width="469" height="647"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Observe que no final imagem temos uma tag &lt;code&gt;1.17.1&lt;/code&gt; e após realizarmos um commit novo no &lt;a href="https://github.com/andraderaul/random-fy/commits/main" rel="noopener noreferrer"&gt;branch de release&lt;/a&gt;, o &lt;strong&gt;semantic-release&lt;/strong&gt; é acionado e cria uma nova tag com a numeração &lt;code&gt;1.17.2&lt;/code&gt;. Em seguida, realizamos dois commits um de docs e outro de fix, quando esses commits vão para o branch de release é acionado novamente e temos uma nova tag &lt;code&gt;1.17.3&lt;/code&gt;. Depois disso, temos mais um commit de feat no branch de release e nossa nova tag é &lt;code&gt;1.18.0&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;E nosso arquivo de &lt;a href="https://github.com/andraderaul/random-fy/blob/main/CHANGELOG.md" rel="noopener noreferrer"&gt;Changelog&lt;/a&gt; fica da seguinte maneira:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfo3a2w8kg7k256fae78.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfo3a2w8kg7k256fae78.png" alt="Na imagem mostra a linha do tempo do Changelog" width="444" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É importante notar que cada tag foi associada a uma release, a tag &lt;code&gt;1.17.1&lt;/code&gt; tem uma release associada e nas notas de release temos os commits que foram feitos naquela tag.&lt;/p&gt;

&lt;p&gt;Observe que existe um commit de docs e ele não foi adicionado nos Changelogs, porém há formas de configurar para que ele apareça.&lt;/p&gt;

&lt;p&gt;Por último, mas não menos importante é possível executar o &lt;strong&gt;semantic-release&lt;/strong&gt; sem acionar a geração de uma nova release, basta executar ele como &lt;code&gt;dry-run&lt;/code&gt;. Isso é uma salvação quando estamos no processo de configuração ou queremos ver o Changelog daquela versão.&lt;/p&gt;

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

&lt;p&gt;Nessa seção descreverei passo a passo de como configurar o &lt;strong&gt;semantic-release&lt;/strong&gt; em um projeto. Uma observação é possível que as versões dos pacotes estejam diferentes, ou seja, mais atualizados após a publicação desse blog post. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Criar um repositório git e adiciona-lo ao remoto no Github ou usar um repositório já existente;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Realizar as configurações necessárias do &lt;a href="https://www.npmjs.com/package/semantic-release" rel="noopener noreferrer"&gt;&lt;strong&gt;semantic-release&lt;/strong&gt;&lt;/a&gt;. 
Note que, se for um projeto novo necessita de &lt;code&gt;yarn init&lt;/code&gt;;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Agora precisamos adicionar o pacote do &lt;strong&gt;semantic-release&lt;/strong&gt; nas dev dependencies;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add semantic-release &lt;span class="nt"&gt;-D&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Em seguida precisamos adicionar os plugins do &lt;strong&gt;semantic-release&lt;/strong&gt;;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add @commitlint/cli @commitlint/config-conventional @semantic-release/changelog @semantic-release/git &lt;span class="nt"&gt;-D&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Cada plugin tem um propósito especifico:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@commitlint/cli&lt;/code&gt;: É um analisador de mensagem de commit para verificar se a mensagem do commit está segundo o padrão;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@commitlint/config-conventional&lt;/code&gt;: É o configurador de um padrão a ser seguido nas mensagens de commit, como por exemplo o padrão do Angular;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@semantic-release/changelog&lt;/code&gt;: Plugin que atualiza ou cria o arquivo de Changelog;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@semantic-release/git&lt;/code&gt;: Plugin que realiza os commits de release e artefatos gerados;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Adicionar o pacote &lt;a href="https://www.npmjs.com/package/husky" rel="noopener noreferrer"&gt;Husky&lt;/a&gt; (opcional):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Esse passo é interessante pois com o husky evitamos de subir commits fora do padrão;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Criar um arquivo &lt;code&gt;.releaserc.json&lt;/code&gt; exemplo disponível na &lt;a href="https://semantic-release.gitbook.io/semantic-release/usage/configuration" rel="noopener noreferrer"&gt;doc&lt;/a&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O arquivo &lt;code&gt;.releaserc.json&lt;/code&gt; ficou da seguinte maneira;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"plugins"&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="s2"&gt;"@semantic-release/commit-analyzer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"@semantic-release/release-notes-generator"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"@semantic-release/github"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"@semantic-release/changelog"&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="s2"&gt;"@semantic-release/npm"&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;"npmPublish"&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="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@semantic-release/git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"assets"&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;"package.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"package-lock.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CHANGELOG.md"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"chore(release): ${nextRelease.version} [skip ci]&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;${nextRelease.notes}"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"branches"&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="s2"&gt;"main"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Criar uma workflow para ser executado no Github action:

&lt;ul&gt;
&lt;li&gt;Criar um &lt;code&gt;.env&lt;/code&gt; com a seguinte key &lt;strong&gt;GITHUB_TOKEN&lt;/strong&gt; e o seu access token do Github;&lt;/li&gt;
&lt;li&gt;Criar um diretório Github workflows com um arquivo dentro: &lt;code&gt;.github/workflows/release.yml&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Temos o arquivo &lt;code&gt;.github/workflows/release.yml&lt;/code&gt; dessa forma;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Release&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;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;release&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&lt;/span&gt;

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

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout&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@v3&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;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&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 Node.js&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@v3&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="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;lts/*'&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;yarn 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;Release&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;GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&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;yarn release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Adicionar o comando do &lt;strong&gt;semantic-release&lt;/strong&gt; nos scripts do &lt;code&gt;package.json&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;Por último o &lt;code&gt;package.json&lt;/code&gt; está assim;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"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;"poc-release"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"index.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"repository"&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;"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;"git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"git@github.com:andraderaul/poc-release.git"&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;"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;"Raul Andrade"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"license"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MIT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&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;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"release"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"semantic-release"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"release:dry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"semantic-release --dry-run"&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;"devDependencies"&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;"@commitlint/cli"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^16.2.3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@commitlint/config-conventional"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^16.2.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@semantic-release/changelog"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^6.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@semantic-release/git"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^10.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"husky"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^7.0.4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"jest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^27.5.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"semantic-release"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^19.0.2"&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;h2&gt;
  
  
  Repositórios
&lt;/h2&gt;

&lt;p&gt;Para ver o código de configuração na íntegra, acesse o repositório no &lt;a href="https://github.com/andraderaul/poc-release" rel="noopener noreferrer"&gt;github&lt;/a&gt;.&lt;br&gt;
As imagens utilizadas nos exemplos são de outro &lt;a href="https://github.com/andraderaul/random-fy" rel="noopener noreferrer"&gt;repositório&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://semantic-release.gitbook.io/semantic-release/usage/configuration" rel="noopener noreferrer"&gt;semantic-release&lt;/a&gt;&lt;br&gt;
&lt;a href="https://semver.org/" rel="noopener noreferrer"&gt;Semantic Versioning 2.0.0&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.conventionalcommits.org/en/v1.0.0/" rel="noopener noreferrer"&gt;Conventional Commits&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>github</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Como criei um Web App utilizando dados do Spotify</title>
      <dc:creator>Raul Andrade</dc:creator>
      <pubDate>Wed, 13 Apr 2022 01:59:08 +0000</pubDate>
      <link>https://dev.to/andraderaul/como-criei-um-web-app-utilizando-dados-do-spotify-1djn</link>
      <guid>https://dev.to/andraderaul/como-criei-um-web-app-utilizando-dados-do-spotify-1djn</guid>
      <description>&lt;h2&gt;
  
  
  Idealização
&lt;/h2&gt;

&lt;p&gt;Há um tempo eu estava pensando como seria criar um Web App utilizando os dados do Spotify, após refletir por alguns dias cheguei na ideia de uma aplicação. Por gostar de sempre escutar música enquanto realizo tarefas, pensei em uma aplicação que me ajudasse a conhecer novas musicas, obviamente dentro do Spotify já existem diversas maneiras de conhecer novas musicas, mas eu queria conhecer do meu próprio jeito.&lt;/p&gt;

&lt;p&gt;Portanto, criei o &lt;a href="https://random-fy.vercel.app/" rel="noopener noreferrer"&gt;Randomfy&lt;/a&gt;, uma aplicação que me permite ouvir a prévia de uma música e decidir se gosto ou não dela por meio de likes e dislikes, muito similar ao Tinder. Quando o usuário logado no &lt;a href="https://random-fy.vercel.app/" rel="noopener noreferrer"&gt;Randomfy&lt;/a&gt; decide que gosta da musica e aperta o botão de like, e o &lt;a href="https://random-fy.vercel.app/" rel="noopener noreferrer"&gt;Randomfy&lt;/a&gt; recomenda uma nova musica com base na musica curtida. &lt;/p&gt;

&lt;h2&gt;
  
  
  Processo burocrático
&lt;/h2&gt;

&lt;p&gt;Legal, mas e o processo para criar a aplicação? O processo para a criação de um App no Spotify é bastante simples, você precisa ter uma conta no Spotify, acessar o &lt;a href="https://developer.spotify.com/" rel="noopener noreferrer"&gt;Spotify para desenvolvedores&lt;/a&gt; com essa mesma conta e preencher um formulário. Após isso você consegue criar quantos Apps desejar clicando em um botão “create an app”.&lt;/p&gt;

&lt;p&gt;Quando você clica no botão é necessário colocar o nome e descrição da aplicação, após isso você consegue ter acesso a sua Dashboard. Com o App criado é possível observar que ele ainda está em modo desenvolvedor e somente 25 pessoas que você deve cadastrar no App podem fazer uso dele, e para aumentar o limite de usuários é necessário submeter extensão de quota. Essa extensão o Spotify pode ou não recusar, pois é necessário informar o motivo da criação do App e como você vai utilizar os dados do Spotify. Minha recomendação é solicitar a extensão somente quando você tiver uma primeira versão pronta, pois no momento da solicitação é necessário enviar printscreen da aplicação e um link para acessa-la. &lt;/p&gt;

&lt;p&gt;Um ponto importante a levar em consideração ao solicitar uma extensão de quota, é se atentar aos &lt;a href="https://developer.spotify.com/terms/" rel="noopener noreferrer"&gt;termos de serviço do desenvolvedor&lt;/a&gt; e &lt;a href="https://developer.spotify.com/documentation/general/design-and-branding/" rel="noopener noreferrer"&gt;diretrizes de branding&lt;/a&gt;, pois quando usamos conteúdo de terceiros precisamos seguir as normas deles. No caso do &lt;a href="https://random-fy.vercel.app/" rel="noopener noreferrer"&gt;Randomfy&lt;/a&gt;, eu arredondei algumas imagens, e no processo de desenvolvimento acabei esquecendo que havia feito isso, então quando solicitei para o Spotify deixar meu App público eles o rejeitaram algumas vezes, até eu observar que este era o problema. Nos emails enviados pelo Spotify eles eram bem específicos, me informando que não estava seguindo as diretrizes de branding, mas na minha cabeça eu estava, e até descobrir isso foram dois dias.&lt;/p&gt;

&lt;p&gt;Ainda sobre a solicitação de extensão de quota, o tempo médio que levava de uma solicitação e a sua resposta é menos de um dia, geralmente eu solicitava a noite e logo pela manha recebia um e-mail me informando se eles haviam ou não aceitado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerações
&lt;/h2&gt;

&lt;p&gt;Com o App criado você pode acessar a documentação e entender como os endpoints funcionam e criar algo incrível. Possui uma parte na documentação do Spotify, onde eles mostram &lt;a href="https://developer.spotify.com/community/showcase" rel="noopener noreferrer"&gt;apps maravilhosos criados pela comunidade&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Por fim, eu particularmente gostei bastante da documentação da API do Spotify, é muito boa e com bastante exemplos de como utilizar. Se você ficou curioso sobre como foi feita a parte técnica do &lt;a href="https://random-fy.vercel.app/" rel="noopener noreferrer"&gt;Randomfy&lt;/a&gt; deixe um comentário para que eu possa saber se devo escrever sobre.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://developer.spotify.com/" rel="noopener noreferrer"&gt;Api Spotify &lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/andraderaul/random-fy/blob/main/README.md" rel="noopener noreferrer"&gt;Readme do Randomfy&lt;/a&gt;&lt;br&gt;
&lt;a href="https://unsplash.com/photos/-XiEdejuJso" rel="noopener noreferrer"&gt;Créditos da imagem de capa&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>braziliandevs</category>
      <category>nextjs</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
