splor-mg / notas

Base de conhecimento
https://splor-mg.github.io/notas/main
0 stars 0 forks source link

Github Actions: Rodar scripts condicionados a modificação em arquivos ou pastas #39

Open labanca opened 2 months ago

labanca commented 2 months ago

Existe no marketplace uma action chamada changed_files que oferece recursos para rastrear facilmente todos os arquivos e diretórios alterados em relação a um branch.

No contexto dos projetos da splor-mg, esse action pode ser utilizado para que determinadas ações dentro de um fluxo somente sejam executadas caso determinadas alterações nos arquivos do repositório aconteçam:

- name: Get changed files
      id: changes
      uses: tj-actions/changed-files@v35
      with:
        files: 'data/**'

    - name: Debug changed files
      run: |
        echo "Any changed: ${{ steps.changes.outputs.any_changed }}"
        echo "All changed files: ${{ steps.changes.outputs.all_changed_files }}"
        echo "Added files: ${{ steps.changes.outputs.added_files }}"
        echo "Modified files: ${{ steps.changes.outputs.modified_files }}"
        echo "Removed files: ${{ steps.changes.outputs.removed_files }}"
      push_depth: 0

O script acima captura todas as alterações feitas na pasta data/ e pode utilizar essas informações de diversas maneiras. No exemplo em questão, mensagens de debug são printadas indicando se aconteceram mudanças, quais arquivos foram criados, modificados e deletados. Esses arquivos (ou variáveis) criados por esse action podem ser utilizadas em outros steps para controlar seu comportamento de execução.

No exemplo abaixo, ao invés de uma pasta, a chave files: do step Get changed files verifica mudanças em um arquivo específico: datapackage.json.

    - name: Get changed files
      id: changes
      uses: tj-actions/changed-files@v35
      with:
        files: 'datapackage.json'

Com isso é executar step subsequente condicionalmente em função das mudanças rastreadas:

    - name: Executes If Datapackage.json changed
      if: steps.changes.outputs.any_changed == 'true'
      run: |
        echo "The datapackage.json file has changed."

O arquivo steps.changes.outputs.any_changed indica se ocorreram mudanças no arquivo datapackage.json e a condicional if determina se o script do step Executes If Datapackage.json changed será executado ou não.


Durante a execução do workflow, caso algum commit seja realizado para o repositório, é possível capturar esses novos arquivos com o action changed_files ainda durante a execução desse mesmo workflow.

O workflow abaixo printa mensagens de debug com as alterações realizadas antes e depois de um push de um arquivo de texto para a pasta data/:

name: Updated

on:
  workflow_dispatch:
  schedule:
    - cron:  '01 9 * * 1-5'
    - cron:  '01 15 * * 1-5'
    - cron:  '01 18 * * 1-5'

jobs:
  all:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout repo
      uses: actions/checkout@v4

    - name: Get changed files 1
      id: changes
      uses: tj-actions/changed-files@v35
      with:
        files: 'data/**'
    - name: Debug changed files
      run: |
        echo "Any changed[1]: ${{ steps.changes.outputs.any_changed }}"
        echo "All changed files[1]: ${{ steps.changes.outputs.all_changed_files }}"
        echo "Added files[1]: ${{ steps.changes.outputs.added_files }}"
        echo "Modified files[1]: ${{ steps.changes.outputs.modified_files }}"
        echo "Removed files[1]: ${{ steps.changes.outputs.removed_files }}"

    - name: Push some files inside the workflow run
      run: |
        git config --global user.name "github-actions[bot]"
        git config --global user.email "github-actions[bot]@users.noreply.github.com"

        echo "This is a dummy file." > data/dummy.txt

        git add data/dummy.txt
        git commit -m "Add dummy file for testing"

        git push origin HEAD:${{ github.ref }}
      env:
        GH_PAT: ${{ secrets.GH_PAT }}

    - name: Get changed files 2
      id: changes2
      uses: tj-actions/changed-files@v35
      with:
        files: 'data/**'
    - name: Debug changed files 2
      run: |
        echo "Any changed[2]: ${{ steps.changes2.outputs.any_changed }}"
        echo "All changed files[2]: ${{ steps.changes2.outputs.all_changed_files }}"
        echo "Added files[2]: ${{ steps.changes2.outputs.added_files }}"
        echo "Modified files[2]: ${{ steps.changes2.outputs.modified_files }}"
        echo "Removed files[2]: ${{ steps.changes2.outputs.removed_files }}"

Resultando no log:

image

O segundo uso do changed_files indica que o commit intermediário foi enxergado pelo action, já que na primeira vez que as mensagens de debug foram mostradas não havia qualquer alteração de arquivos no repositório. Notar que deve ser utilizada uma nova instância do changed_files com uma id diferente, nesse case changes2, pois a anterior, naturalmente mantém o estado do momento anterior ao commit do arquivo dummy.

fjuniorr commented 2 months ago

Você chegou a entender se houver commits locais depois que o repositório foi clonado se as mudanças vão ser do último commit local?

labanca commented 2 months ago

Você chegou a entender se houver commits locais depois que o repositório foi clonado se as mudanças vão ser do último commit local?

Atualizei o texto para conter o comportamento com commits intermediários, mas acho que ainda não era isso exatamente que você estava perguntando @fjuniorr.

fjuniorr commented 2 months ago

Era exatamente isso!