Ações do GitHub como CI/CD para um site em um gerador estático e páginas do GitHub

Ações do GitHub como CI/CD para um site em um gerador estático e páginas do GitHub

Depois de vasculhar Habr um pouco, fiquei surpreso ao ver que poucos artigos foram publicados sobre o tópico do recurso (beta) do GitHub - Ações.

Parece que tal eufemismo pode ser explicado pelo fato de a funcionalidade ainda estar em testes, ainda que “beta”. Mas é um recurso útil da versão beta que permite que esta ferramenta seja usada em repositórios privados. É sobre como trabalhar com essa tecnologia que falarei neste artigo.

Pré-história

Se começarmos em ordem, provavelmente vale a pena mencionar que no processo de busca por uma opção rápida, conveniente, fácil e gratuita para armazenar um site pessoal “Sobre mim”, tive que passar várias noites vasculhando muitos artigos.

Algumas pessoas escolhem hospedagem, outras um servidor em nuvem, e quem não quer entender o trabalho, a interação e o pagamento de tudo isso gosta de fazer upload de sites estáticos para um repositório, já que agora isso pode ser feito tanto no GitHub quanto no GitLab.

Claro, esta é uma escolha pessoal de cada um.

Minha escolha final foi GitHub Pages.

Sobre páginas

Quem não conhece gh-pages - é uma opção de armazenamento de documentação em forma de site e é disponibilizada gratuitamente, sendo que além da documentação também se propõe o armazenamento de sites pessoais. Esta funcionalidade é fornecida pelo GitHub a todos os usuários e está disponível nas configurações do repositório.

O repositório do projeto usa uma ramificação gh-pages, para um site de usuário - um repositório separado com o nome username.github.io com fontes do site em master ramo.

você pode ver mais na documentação, mas deixe-me apenas observar que o GitHub é surpreendentemente generoso ao permitir que qualquer pessoa vincule seu próprio domínio a tal site simplesmente adicionando um arquivo CNAME com o nome de domínio e configurando o DNS do seu provedor de domínio nos servidores GitHub.

Tenho certeza que há muitos artigos aqui sobre como desenvolver um site desse tipo, então não é sobre isso que falarei mais adiante.

Problema surgindo

O problema é que ao usar um gerador estático, há necessidade de escrever scripts adicionais e usar bibliotecas para simplificar o processo de geração de páginas e carregá-las no repositório. Simplesmente, se você armazenar as fontes em um repositório privado separado, então toda vez que houver alguma alteração no site, será necessário implantar o ambiente local para a posterior geração de páginas estáticas e publicação no repositório principal do site.

Há uma abundância geradores estáticos e todos eles têm o mesmo problema. Essas ações exigem muito tempo e esforço e, em última análise, tornam o trabalho no site mais lento, especialmente após várias migrações de sistema operacional para sistema operacional ou incidentes com perda de dados em discos rígidos (este foi o caso no meu caso).

Recentemente, seja em uma notificação pop-up no site ou em uma newsletter do GitHub, foi notado um CI/CD recém-construído, que permitiu que essas ações fossem realizadas com o mínimo esforço.

Sobre geradores de páginas estáticas

Não vou focar atenção especial neste subitem, mas compartilharei algumas teses que encontrei durante a seleção e utilização dos seguintes:

1) escolha um gerador que se adapte à sua linguagem de programação ou que seja o mais claro possível. Tive essa ideia num momento em que eu mesmo tive que adicionar algumas funcionalidades para o site funcionar, adicionar muletas para sua maior estabilidade e automação. Além disso, este é um bom motivo para você mesmo escrever funcionalidades adicionais na forma de plug-ins;

2) qual gerador escolher é uma escolha pessoal, mas vale considerar que para a imersão inicial no trabalho da funcionalidade GitHub Pages, você deve primeiro instalar Jekyll. Felizmente, ele permite gerar um site a partir de fontes diretamente no repositório (Vou repetir isso com a minha escolha).

Minha escolha do gerador é baseada no primeiro ponto. Pelicano que está escrito em Python substituiu facilmente Jekyll, o que é estranho para mim (usei por quase um ano). Como resultado, até mesmo criar e editar artigos e trabalhar em um site proporciona experiência adicional em um idioma que é interessante para mim.

__

Formulação do problema

A principal tarefa será escrever um script (na verdade, um arquivo de configuração) que geraria automaticamente páginas estáticas a partir de um repositório privado. A solução envolverá a funcionalidade de um ambiente virtual. O próprio script adicionará páginas prontas ao repositório público.

Ferramentas para solução

Ferramentas que usaremos para resolver o problema:

  • Ações do GitHub;
  • Python3.7;
  • Pelicano;
  • Git;
  • Páginas do GitHub.

A solução

Assim, depois de conhecer um pouco a documentação e entender como são escritos os scripts de Actions, ficou claro que esse mecanismo resolverá completamente o problema que surgiu. No momento em que este artigo foi escrito, você deveria se inscrever para usar esta funcionalidade. para testes beta!

Ações do GitHub como CI/CD para um site em um gerador estático e páginas do GitHub
Descrição da nova funcionalidade pelo próprio Github

Escrever um script Actions começa criando um arquivo nomeado em uma pasta .github e sua subpasta workflows. Isso pode ser feito manualmente ou no editor na guia Ações na página do repositório.

Ações do GitHub como CI/CD para um site em um gerador estático e páginas do GitHub
Exemplo de formulário de script em branco

Vou comentar brevemente sobre o formulário

name: CI    # название скрипта: будет отображаться во вкладке Actions

on: [push]  # действие, по которому запускается данный скрипт

jobs:       # роботы, которые будут выполняться
  build:    # сборка, которая..

    runs-on: ubuntu-latest      # ..будет запущена на основе этого образа

    steps:              # шаги которые будут проделаны после запуска образа
    - uses: actions/checkout@v1     # переход в самую актуальную ветку
    - name: Run a one-line script   # имя работы номер 1
      run: echo Hello, world!       # суть работы номер 1 (bash-команда записана в одну строку)
    - name: Run a multi-line script   # имя работы номер 2
      run: |                    # суть работы номер 2 (многострочная)
        echo Add other actions to build,
        echo test, and deploy your project.

Vamos escrever o nosso próprio com base no modelo:

0) Você também pode deixar o nome “CI”. É uma questão de gosto.

1) Em seguida, você precisa selecionar a ação/gatilho que irá lançar o script, no nosso caso este é o push usual de um novo commit para o repositório.

on:
  push

2) Deixaremos também a imagem com base na qual o script será lançado como exemplo, já que o Ubuntu está bastante satisfeito com as funcionalidades necessárias. Olhando para ferramentas disponíveis fica claro que pode ser qualquer imagem necessária ou simplesmente conveniente (ou um contêiner Docker baseado nela).

  build:
    runs-on: ubuntu-latest

3) Nas etapas, primeiro configuraremos o ambiente para nos prepararmos para o trabalho principal.

3.1) vá para a filial que precisamos (etapa padrão checkout):

- uses: actions/checkout@v1

3.2) instale o Python:

    - name: Set up Python
      uses: actions/setup-python@v1
      with:
        python-version: 3.7

3.3) instale as dependências do nosso gerador:

    - name: Install dependencies
      run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

3.4) crie um diretório no qual serão geradas as páginas do site:

   - name: Make output folder
      run: mkdir output

4) Para que o trabalho no site seja consistente, nomeadamente, não eliminar alterações anteriores e poder adicionar alterações ao repositório do site sem conflitos, o próximo passo será clonar o repositório do site de cada vez:

   - name: Clone master branch
      run: git clone "https://${{ secrets.ACCESS_TOKEN }}@github.com/${GITHUB_ACTOR}/${GITHUB_ACTOR}.github.io.git" --branch master --single-branch ./output

Esta etapa chama variáveis ​​do sistema:

  • variável GITHUB_ACTOR O GitHub se instala sozinho e este é o nome de usuário por cuja culpa este script foi iniciado;
  • variável secrets.ACCESS_TOKEN isso é gerado token para gerenciar o Github, podemos passá-la como uma variável de ambiente configurando-a na aba Secrets nossas configurações do repositório. Observe que durante a geração o token nos será fornecido uma vez e não haverá mais acesso a ele. Bem como os valores dos itens Secretos.

5) Vamos prosseguir para a geração de nossas páginas:

   - name: Generate static pages
      run: pelican content -o output -s publishconf.py

Os parâmetros passados ​​ao gerador são responsáveis ​​pelo diretório para onde serão enviados os arquivos gerados (-o output) e o arquivo de configuração que usamos para gerar (-s publishconf.py; Você pode ler sobre a abordagem para separar a configuração local e a configuração para publicação na documentação do Pelican).

Deixe-me lembrá-lo do que está em nossa pasta output O repositório do site já foi clonado.

6) Vamos configurar o git e indexar nossos arquivos alterados:

    - name: Set git config and add changes
      run: |
          git config --global user.email "${GITHUB_ACTOR}@https://users.noreply.github.com/"
          git config --global user.name "${GITHUB_ACTOR}"
          git add --all
      working-directory: ./output

Neste ponto, é utilizada uma variável já conhecida e é indicado o diretório de trabalho onde serão lançados os comandos desta etapa. Caso contrário, o comando para ir para o diretório de trabalho seria semelhante a - cd output.

7) Vamos gerar uma mensagem de commit, confirmar as alterações e enviá-las para o repositório. Para que o commit não seja em vão e portanto não produza erro no bash (o resultado da saída não é 0) — primeiro, vamos verificar se é necessário fazer commit e push de algo. Para fazer isso usamos o comando git diff-index --quiet --cached HEAD -- que será enviado para o terminal 0 se não houver alterações em relação à versão anterior do site, e 1 existem tais mudanças. Em seguida, processamos o resultado deste comando. Assim, nas informações sobre a execução do script, registraremos informações úteis sobre o estado do site nesta fase, ao invés de travar automaticamente e nos enviar um relatório sobre a falha do script.

Também realizamos essas ações em nosso diretório com páginas prontas.

   - name: Push and send notification
      run: |
          COMMIT_MESSAGE="Update pages on $(date +'%Y-%m-%d %H:%M:%S')"
          git diff-index --quiet --cached HEAD -- && echo "No changes!" && exit 0 || echo $COMMIT_MESSAGE
          # Only if repo have changes
          git commit -m "${COMMIT_MESSAGE}"
          git push https://${{ secrets.ACCESS_TOKEN }}@github.com/${GITHUB_ACTOR}/${GITHUB_ACTOR}.github.io.git master
      working-directory: ./output

resultado

Como resultado, esse script permite que você não pense em criar páginas estáticas. Ao adicionar alterações diretamente a um repositório privado, seja trabalhando com git em qualquer sistema ou criando um arquivo por meio da interface web do GitHub, o Actions fará tudo sozinho. Se o script travar inesperadamente, uma notificação será enviada para seu e-mail.

Código completo

Deixarei minha versão de trabalho, na qual a última etapa adiciona o envio de uma notificação de que um commit foi enviado para o repositório principal.

São utilizados os Secrets descritos acima, onde são adicionados o token do bot e o ID do usuário para quem a mensagem precisa ser enviada.

name: Push content to the user's GitHub pages repository

on:
  push

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1
    - name: Set up Python
      uses: actions/setup-python@v1
      with:
        python-version: 3.7
    - name: Install dependencies
      run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
    - name: Make output folder
      run: mkdir output
    - name: Clone master branch
      run: git clone "https://${{ secrets.ACCESS_TOKEN }}@github.com/${GITHUB_ACTOR}/${GITHUB_ACTOR}.github.io.git" --branch master --single-branch ./output
    - name: Generate static pages
      run: pelican content -o output -s publishconf.py
    - name: Set git config and add changes
      run: |
          git config --global user.email "${GITHUB_ACTOR}@https://users.noreply.github.com/"
          git config --global user.name "${GITHUB_ACTOR}"
          git add --all
      working-directory: ./output
    - name: Push and send notification
      run: |
          COMMIT_MESSAGE="Update pages on $(date +'%Y-%m-%d %H:%M:%S')"
          git diff-index --quiet --cached HEAD -- && echo "No changes!" && exit 0 || echo $COMMIT_MESSAGE
          git commit -m "${COMMIT_MESSAGE}"
          git push https://${{ secrets.ACCESS_TOKEN }}@github.com/${GITHUB_ACTOR}/${GITHUB_ACTOR}.github.io.git master
          curl "https://api.telegram.org/bot${{ secrets.BOT_TOKEN }}/sendMessage?text=$COMMIT_MESSAGE %0ALook at ${GITHUB_ACTOR}.github.io %0ARepository%3A github.com/${GITHUB_ACTOR}/${GITHUB_ACTOR}.github.io&chat_id=${{ secrets.ADMIN_ID }}"
      working-directory: ./output

Screenshots

Ações do GitHub como CI/CD para um site em um gerador estático e páginas do GitHub
O resultado de uma das execuções exibida na guia Ações do repositório de origem

Ações do GitHub como CI/CD para um site em um gerador estático e páginas do GitHub
Mensagem do bot sobre a conclusão do script

Links úteis

Compreendendo as ações
Sintaxe de ações
Lista de gatilhos
Opções para ambientes virtuais
Páginas do Github
Lista de gerador estático

Fonte: habr.com

Adicionar um comentário