name: Deploy

on:
  workflow_dispatch:
    inputs:
        publish-pypi:
            type: boolean
            description: Publish to PyPI
  release:
    types:
    - published

jobs:
  determine-source-date-epoch:
    name: "Determine SOURCE_DATE_EPOCH"
    runs-on: ubuntu-latest
    outputs:
      source-date-epoch: ${{ steps.log.outputs.source-date-epoch }}

    steps:
      - uses: actions/checkout@v5
        with:
          submodules: true
          fetch-depth: 0

      - id: log
        name: Compute SOURCE_DATE_EPOCH
        run: |
          # Find latest unix timestamp in awkward-cpp, and the kernel generation files
          epoch=$( git log -1 --format=%at -- awkward-cpp kernel-specification.yml kernel-test-data.json )
          echo "source-date-epoch=$epoch" >> $GITHUB_OUTPUT

  check-requirements:
    name: "Check awkward requirements"
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v5
        with:
          submodules: true

      - name: Check awkward-cpp version matches requirement
        run: pipx run nox -s check_cpp_constraint

  check-cpp-on-pypi:
    name: "Check awkward-cpp dependency on PyPI"
    runs-on: ubuntu-latest
    needs: [determine-source-date-epoch]
    env:
      SOURCE_DATE_EPOCH: ${{ needs.determine-source-date-epoch.outputs.source-date-epoch }}

    steps:
      - uses: actions/checkout@v5
        with:
          submodules: true

      - name: Prepare build files
        run: pipx run nox -s prepare

      - name: Build awkward-cpp sdist
        run: pipx run build --sdist awkward-cpp

      - name: Check sdist matches PyPI
        run: pipx run nox -s check_cpp_sdist_released -- awkward-cpp/dist/awkward_cpp*.tar.gz

  build:
    name: "Build wheel & sdist"
    runs-on: ubuntu-latest
    needs: [determine-source-date-epoch]
    permissions:
      id-token: write
      attestations: write
      contents: read
    env:
      SOURCE_DATE_EPOCH: ${{ needs.determine-source-date-epoch.outputs.source-date-epoch }}
    steps:
    - uses: actions/checkout@v5
      with:
        submodules: true

    - name: Prepare build files
      run: pipx run nox -s prepare

    - name: Build distributions
      run: pipx run build

    - name: Check metadata
      run: pipx run twine check dist/*

    - name: Generate artifact attestation for sdist and wheel
      uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
      with:
        subject-path: "dist/awkward-*"

    - uses: actions/upload-artifact@v5
      with:
        name: distributions
        path: dist/*

  bundle-headers:
    name: "Bundle header-only libraries"
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v5
    - uses: actions/upload-artifact@v5
      with:
        name: header-only
        path: header-only

  upload:
    needs: [build, check-requirements, check-cpp-on-pypi]
    runs-on: ubuntu-latest
    if: (github.event_name == 'release' && github.event.action == 'published') || inputs.publish-pypi
    permissions:
      id-token: write
    environment:
      name: "pypi"
      url: "https://pypi.org/project/awkward/"
    steps:
    - uses: actions/download-artifact@v6
      with:
        name: distributions
        path: dist

    - name: List distributions to be deployed
      run: ls -l dist/

    - name: Verify sdist artifact attestation
      env:
        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: gh attestation verify dist/awkward-*.tar.gz --repo ${{ github.repository }}

    - name: Verify wheel artifact attestation
      env:
        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: gh attestation verify dist/awkward-*.whl --repo ${{ github.repository }}

    - uses: pypa/gh-action-pypi-publish@v1.13.0

  publish-headers:
    name: "Publish header-only libraries alongside release"
    runs-on: ubuntu-latest
    needs: [bundle-headers]
    if: github.event_name == 'release' && github.event.action == 'published'
    steps:
    - uses: actions/download-artifact@v6
      with:
        name: header-only
        path: header-only
    - name: Create archive
      run: |
        # Don't include `header-only` parent directory
        env -C header-only/ zip -r header-only.zip .
    - uses: softprops/action-gh-release@v2
      with:
        files: header-only/header-only.zip
