djangogithub-actionsgithub-pagescollectstatic

Automate Deployment to GitHub Pages with Django Collectstatic [GitHub Actions Beginner]


I have two workflows for GitHub Actions. One has the task of deploying the static assets of the prod branch, while the other one has the task of running the Django collectstatic command.

I want to merge both processes for the automatic deployment of new static elements, so I don't have to run collectstatic each time before pushing changes. The problem is that I don't have any idea how.

Workflow for deploying static assets

# Simple workflow for deploying static content to GitHub Pages
name: Deploy static content to Pages

on:
  # Runs on pushes targeting the default branch
  push:
    branches: ["prod"]

  pull_request:
    branches: ["prod"]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
  contents: read
  pages: write
  id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  # Single deploy job since we're just deploying
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          ref: 'prod'
      - name: Setup Pages
        uses: actions/configure-pages@v5
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: './assets'
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

Workflow for django collectstatic

name: Django CI

on:
  push:
    branches: [ "prod" ]
  pull_request:
    branches: [ "prod" ]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      max-parallel: 4
      matrix:
        python-version: [3.12]

    steps:
    - uses: actions/checkout@v4
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v3
      with:
        python-version: ${{ matrix.python-version }}
    - name: Setup Poetry
      # You may pin to the exact commit or the version.
      # uses: Gr1N/setup-poetry@48b0f77c8c1b1b19cb962f0f00dff7b4be8f81ec
      uses: Gr1N/setup-poetry@v9
      with:
        # Allow to install prerelease versions of Poetry
        poetry-preview: false # optional, default is false
        # Poetry version to use, if version is not provided then latest stable version will be used
        poetry-version: 1.8.3 # optional
    - name: Install Dependencies
      run: poetry install
    - name: Collect static
      env:
        SECRET_KEY: ${{ secrets.SECRET_KEY }}
        # All the secret variables ...
      run: poetry run python manage.py collectstatic --noinput

PS. I use poetry in my project, so I am using the GitHub action Setup Poetry to run Python commands.


Solution

  • I resolved it with some help from ChatGPT. It looks like I could define both tasks in the same file using jobs. The first job collects the static files and uploads them as an artifact, and the second job downloads them and then deploys to GitHub Pages.

    Here is the code:

    name: Collect static and deploy to Pages
    
    on:
      push:
        branches: ["prod"]
      pull_request:
        branches: ["prod"]
      workflow_dispatch:
    
    permissions:
      contents: read
      pages: write
      id-token: write
      
    concurrency:
      group: "pages"
      cancel-in-progress: false
    
    jobs:
      collectstatic:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout code
            uses: actions/checkout@v4
            with:
              ref: 'prod'
    
          - name: Set up Python
            uses: actions/setup-python@v3
            with:
              python-version: 3.12
    
          - name: Setup Poetry
            uses: Gr1N/setup-poetry@v9
            with:
              poetry-preview: false
              poetry-version: 1.8.3
    
          - name: Install dependencies
            run: poetry install
    
          - name: Collect static
            env:
              SECRET_KEY: ${{ secrets.SECRET_KEY }}
              # ...
            run: poetry run python manage.py collectstatic --noinput
    
          - name: Archive static files
            uses: actions/upload-artifact@v3
            with:
              name: assets
              path: assets/
    
      deploy:
    
        environment:
          name: github-pages
          url: ${{ steps.deployment.outputs.page_url }}
        runs-on: ubuntu-latest
        needs: collectstatic
        steps:
          - name: Checkout
            uses: actions/checkout@v4
            with:
              ref: 'prod'
    
          - name: Download static files
            uses: actions/download-artifact@v3
            with:
              name: assets
              path: ./assets
    
          - name: Setup Pages
            uses: actions/configure-pages@v5
    
          - name: Upload artifact
            uses: actions/upload-pages-artifact@v3
            with:
              path: './assets'
    
          - name: Deploy to GitHub Pages
            id: production
            uses: actions/deploy-pages@v4
    

    I'm not sure how actions and artifacts are supposed to work, but maybe I could have done it in a single job without needing to upload the files as artifacts.

    I'll be happy to read other answers or corrections; meanwhile, this solved my problem.