summaryrefslogtreecommitdiff
path: root/.github/workflows/publish.yaml
blob: 543bdb33a57bacf2dbefb00b25150fab414154c3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
name: Publish
on:
  push:
    tags:
      - '*'
  # When a new version of Python is released, the workflow can be run manually to
  # publish new wheels for the existing tag.
  workflow_dispatch:
    inputs:
      tag:
        description: 'git tag to check out and upload to'
        required: true
      python:
        description: 'Python version, like "cp311"'
        required: true
jobs:
  sdist:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3
        with:
          ref: ${{ inputs.tag }}
      - uses: actions/setup-python@d27e3f3d7c64b4bbf8e4abfb9b63b83e846e0435
        with:
          python-version: '3.x'
          cache: 'pip'
          cache-dependency-path: 'requirements/*.txt'
      - run: pip install -r requirements/build.txt
      # Use the commit date instead of the current date during the build.
      - run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
      - run: python -m build --sdist
      - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce
        with:
          path: ./dist
        # The sdist is not needed on new Python version builds. However, this job must
        # present in the run for the hash job, so only the upload is skipped.
        if: github.event_name == 'push'
  wheels:
    name: wheels / ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
    steps:
      - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3
      - run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
      - name: Set up QEMU
        if: runner.os == 'Linux'
        uses: docker/setup-qemu-action@e81a89b1732b9c48d79cd809d8d81d79c4647a18
        with:
          platforms: arm64
      - uses: joerick/cibuildwheel@5e15bb25b428e1bf2daf2215f173d2b40135f56f
        env:
          # For workflow_dispatch, only build the new Python version.
          CIBW_BUILD: "${{ inputs.python && format('{0}-*', inputs.python) || null }}"
          CIBW_SKIP: 'pp*'
          CIBW_ARCHS_LINUX: auto aarch64
          CIBW_ARCHS_MACOS: auto universal2
          CIBW_BUILD_FRONTEND: build
          CIBW_ENVIRONMENT_PASS_LINUX: SOURCE_DATE_EPOCH
      - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce
        with:
          path: ./wheelhouse
  hash:
    # Generate hashes for the sdist and wheels, used later for provenance.
    needs: ['sdist', 'wheels']
    runs-on: ubuntu-latest
    outputs:
      hash: ${{ steps.hash.outputs.hash }}
    steps:
      - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a
      - name: generate hash
        id: hash
        run: cd artifact && echo "hash=$(sha256sum * | base64 -w0)" >> $GITHUB_OUTPUT
  provenance:
    needs: ['hash']
    permissions:
      actions: read
      id-token: write
      contents: write
    # Can't pin with hash due to how this workflow works.
    uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.5.0
    with:
      base64-subjects: ${{ needs.hash.outputs.hash }}
      # When building more wheels, use the Python version as the provenance file name.
      provenance-name: ${{ inputs.python && format('{0}.intoto.jsonl', inputs.python) || null }}
  create-release:
    # Upload the sdist, wheels, and provenance to a GitHub release. They remain
    # available as build artifacts for a while as well.
    needs: ['provenance']
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a
      # When building a new tag, create a new draft release.
      - if: github.event_name == 'push'
        name: create release
        run: >
          gh release create --draft --repo ${{ github.repository }}
          ${{ inputs.tag || github.ref_name }}
          *.intoto.jsonl/* artifact/*
        env:
          GH_TOKEN: ${{ github.token }}
      # When running manually, update the existing release with more files.
      - if: github.event_name == 'workflow_dispatch'
        name: update release
        run: >
          gh release upload --repo ${{ github.repository }}
          ${{ inputs.tag || github.ref_name }}
          *.intoto.jsonl/* artifact/*
        env:
          GH_TOKEN: ${{ github.token }}
  publish-pypi:
    needs: ['provenance']
    # Wait for approval before attempting to upload to PyPI. This allows reviewing the
    # files in the draft release.
    environment: 'publish'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a
      # Try uploading to Test PyPI first, in case something fails.
      - uses: pypa/gh-action-pypi-publish@29930c9cf57955dc1b98162d0d8bc3ec80d9e75c
        with:
          password: ${{ secrets.TEST_PYPI_TOKEN }}
          repository_url: https://test.pypi.org/legacy/
          packages_dir: artifact/
          skip_existing: true
      - uses: pypa/gh-action-pypi-publish@29930c9cf57955dc1b98162d0d8bc3ec80d9e75c
        with:
          password: ${{ secrets.PYPI_TOKEN }}
          packages_dir: artifact/
          skip_existing: true