---
# System prepended metadata

title: GitHub Actions Best Practices

---

# GitHub Actions Best Practices

- Author: Thang Bui Quang
- These are some common use cases and best practices of GH Actions that I usually do in my currrent job.

### 1. Conditional jobs run even if some are skipped.

```yaml=
jobs:
  job1: # Run
  job2: # Skipped
  report:
    name: Report Status Check
    needs: [job1, job2]
    if: always()
```

### 2. Conditional jobs based on changed files in PR or latest commit.

```yaml=
jobs:
  check:
    name: Check files changed
    outputs:
      run_job1: ${{ steps.changes.outputs.job1 }}
      run_job2: ${{ steps.changes.outputs.job2 }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 2

      - id: changes
        uses: dorny/paths-filter@v3
        with:
          filters: |
            job1:
              - "path_job1_folder/**"
            job2:
              - "path_job2_folder/**"

  job1:
    needs: check
    if: needs.check.outputs.run_job1 == 'true' 
    
  job2:
    needs: check
    if: needs.check.outputs.run_job2 == 'true' 
```

### 3. Delete workflow history

```bash=
# Install jq, gh on ubuntu/debian
sudo apt-get install jq 
sudo mkdir -p -m 755 /etc/apt/keyrings && wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
&& sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
&& sudo apt update \
&& sudo apt install gh -y

# Install jq, gh on MacOS
brew install jq
brew install gh
```

```bash=
# Login
gh auth login
```

```bash=
export DISPLAY_WORKFLOW_NAME='Build Docker Image'
gh run list \
  --limit 500 \
  --workflow $DISPLAY_WORKFLOW_NAME \
  --json databaseId | \
  jq -r '.[] | .databaseId | @sh' | \
  xargs -I{} gh run delete "{}"
```

### 4. Composite Actions Comment On PR

> Usage:
> ```yaml
> - name: Report Status
>   uses: comment-on-pr-path-repo@main
>   with:
>     message: |
>       ## CI Report
> 
>       | Service | Status Check             | Time  |
>       | ------- | ------------------------ | ----- |
>       | Job 1   | ${{ needs.job1.result }} |       |
> 
>       > [!NOTE]
>       > Some notes
>   if: always()
> ```

```yaml=
name: Comment Pull Request

inputs:
  message:
    description: 'Comment Body'
    default: 'No message provided'
    required: true
  github-token:
    description: 'GitHub Token'
    required: false
    default: ${{ github.token }}

runs:
  using: "composite"
  steps:
    - name: Check if Pull Request
      shell: bash
      run: |
        if [ -z "$GITHUB_HEAD_REF" ]; then
          echo "This is not a pull request. Exiting..."
          exit 1
        fi

    - name: Comment on Pull Request
      uses: actions/github-script@v7
      with:
        github-token: ${{ inputs.github-token }}
        script: |
          const commentBody = `
            ${{ inputs.message }}
          `;
          github.rest.issues.createComment({
            issue_number: context.issue.number,
            owner: context.repo.owner,
            repo: context.repo.repo,
            body: commentBody
          });
```