|
| 1 | +# Pre-release workflow: Build and publish dev packages to Cloudsmith for manual testing. |
| 2 | +# |
| 3 | +# Trigger by either: |
| 4 | +# 1. Adding the 'pre-release' label to a PR |
| 5 | +# 2. Commenting '/pre-release' on a PR (must be repo collaborator) |
| 6 | +# |
| 7 | +# The pre-release version is {base}.dev{pr_number}{epoch} (e.g. 1.13.0.dev421741712838). |
| 8 | +# Each re-trigger produces a unique version so previous pre-releases are preserved. |
| 9 | + |
| 10 | +name: Pre-release |
| 11 | + |
| 12 | +on: |
| 13 | + pull_request: |
| 14 | + types: [labeled] |
| 15 | + issue_comment: |
| 16 | + types: [created] |
| 17 | + |
| 18 | +concurrency: |
| 19 | + group: pre-release-${{ github.event.pull_request.number || github.event.issue.number }} |
| 20 | + cancel-in-progress: true |
| 21 | + |
| 22 | +jobs: |
| 23 | + pre-release: |
| 24 | + name: Build and publish pre-release |
| 25 | + # Trigger on 'pre-release' label OR '/pre-release' comment from a collaborator |
| 26 | + if: >- |
| 27 | + (github.event_name == 'pull_request' && |
| 28 | + github.event.label.name == 'pre-release') || |
| 29 | + (github.event_name == 'issue_comment' && |
| 30 | + github.event.issue.pull_request && |
| 31 | + startsWith(github.event.comment.body, '/pre-release') && |
| 32 | + contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) |
| 33 | + runs-on: ubuntu-latest |
| 34 | + permissions: |
| 35 | + id-token: write |
| 36 | + contents: read |
| 37 | + pull-requests: write |
| 38 | + env: |
| 39 | + CLOUDSMITH_NAMESPACE: ${{ vars.CLOUDSMITH_NAMESPACE }} |
| 40 | + CLOUDSMITH_SVC_SLUG: ${{ vars.CLOUDSMITH_SVC_SLUG }} |
| 41 | + steps: |
| 42 | + - name: React to slash command |
| 43 | + if: github.event_name == 'issue_comment' |
| 44 | + env: |
| 45 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 46 | + COMMENT_ID: ${{ github.event.comment.id }} |
| 47 | + REPO: ${{ github.repository }} |
| 48 | + run: | |
| 49 | + gh api "repos/${REPO}/issues/comments/${COMMENT_ID}/reactions" \ |
| 50 | + -f content=eyes --silent |
| 51 | +
|
| 52 | + - name: Resolve PR details |
| 53 | + id: pr |
| 54 | + env: |
| 55 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 56 | + EVENT_NAME: ${{ github.event_name }} |
| 57 | + ISSUE_NUMBER: ${{ github.event.issue.number }} |
| 58 | + PR_NUMBER_LABEL: ${{ github.event.pull_request.number }} |
| 59 | + REPO: ${{ github.repository }} |
| 60 | + run: | |
| 61 | + if [ "${EVENT_NAME}" = "issue_comment" ]; then |
| 62 | + PR_NUMBER="${ISSUE_NUMBER}" |
| 63 | + else |
| 64 | + PR_NUMBER="${PR_NUMBER_LABEL}" |
| 65 | + fi |
| 66 | + echo "number=${PR_NUMBER}" >> "${GITHUB_OUTPUT}" |
| 67 | +
|
| 68 | + PR_JSON=$(gh api "repos/${REPO}/pulls/${PR_NUMBER}") |
| 69 | + echo "sha=$(echo "${PR_JSON}" | jq -r .head.sha)" >> "${GITHUB_OUTPUT}" |
| 70 | +
|
| 71 | + # Block builds from forked PRs (the fork code would run with repo secrets) |
| 72 | + IS_FORK=$(echo "${PR_JSON}" | jq -r '.head.repo.fork // false') |
| 73 | + if [ "${IS_FORK}" = "true" ]; then |
| 74 | + echo "::error::Pre-release builds are not supported for PRs from forks" |
| 75 | + exit 1 |
| 76 | + fi |
| 77 | +
|
| 78 | + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 |
| 79 | + with: |
| 80 | + ref: ${{ steps.pr.outputs.sha }} |
| 81 | + persist-credentials: false |
| 82 | + |
| 83 | + - name: Set up Python 3.10 |
| 84 | + uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # 6.1.0 |
| 85 | + with: |
| 86 | + python-version: "3.10" |
| 87 | + |
| 88 | + - name: Set pre-release version |
| 89 | + id: version |
| 90 | + env: |
| 91 | + PR_NUMBER: ${{ steps.pr.outputs.number }} |
| 92 | + run: | |
| 93 | + BASE_VERSION=$(cat VERSION) |
| 94 | + EPOCH=$(date +%s) |
| 95 | + PRE_VERSION="${BASE_VERSION}.dev${PR_NUMBER}${EPOCH}" |
| 96 | + echo "${PRE_VERSION}" > VERSION |
| 97 | + echo "${PRE_VERSION}" > cloudsmith_cli/data/VERSION |
| 98 | + echo "version=${PRE_VERSION}" >> "${GITHUB_OUTPUT}" |
| 99 | +
|
| 100 | + - name: Install build dependencies |
| 101 | + run: | |
| 102 | + python -m pip install --upgrade pip |
| 103 | + pip install setuptools wheel |
| 104 | +
|
| 105 | + - name: Build packages |
| 106 | + run: python setup.py sdist bdist_wheel |
| 107 | + |
| 108 | + - name: Install and authenticate Cloudsmith CLI |
| 109 | + uses: cloudsmith-io/cloudsmith-cli-action@76c8ff51a34bea1036d9b7708f10a929624a1910 # v2.0.1 |
| 110 | + with: |
| 111 | + oidc-namespace: ${{ vars.CLOUDSMITH_NAMESPACE }} |
| 112 | + oidc-service-slug: ${{ vars.CLOUDSMITH_SVC_SLUG }} |
| 113 | + |
| 114 | + - name: Publish to Cloudsmith |
| 115 | + env: |
| 116 | + PKG_REPO: ${{ vars.CLOUDSMITH_NAMESPACE }}/cli |
| 117 | + run: | |
| 118 | + cloudsmith push python "${PKG_REPO}" dist/*.tar.gz --republish |
| 119 | + cloudsmith push python "${PKG_REPO}" dist/*.whl --republish |
| 120 | +
|
| 121 | + - name: Comment on PR with install instructions |
| 122 | + env: |
| 123 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 124 | + VERSION: ${{ steps.version.outputs.version }} |
| 125 | + PR_NUMBER: ${{ steps.pr.outputs.number }} |
| 126 | + HEAD_SHA: ${{ steps.pr.outputs.sha }} |
| 127 | + REPO: ${{ github.repository }} |
| 128 | + CS_NS: ${{ vars.CLOUDSMITH_NAMESPACE }} |
| 129 | + run: | |
| 130 | + cat > /tmp/comment.md << COMMENT |
| 131 | + 🚀 **Pre-release \`${VERSION}\` published to Cloudsmith!** |
| 132 | +
|
| 133 | + Install with: |
| 134 | + \`\`\` |
| 135 | + pip install --extra-index-url https://dl.cloudsmith.io/public/${CS_NS}/cli/python/simple/ cloudsmith-cli==${VERSION} |
| 136 | + \`\`\` |
| 137 | +
|
| 138 | + _Built from ${HEAD_SHA}_ |
| 139 | + COMMENT |
| 140 | + gh pr comment "${PR_NUMBER}" --repo "${REPO}" --body-file /tmp/comment.md |
| 141 | +
|
| 142 | + - name: Remove pre-release label |
| 143 | + if: github.event_name == 'pull_request' |
| 144 | + env: |
| 145 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 146 | + PR_NUMBER: ${{ steps.pr.outputs.number }} |
| 147 | + REPO: ${{ github.repository }} |
| 148 | + run: | |
| 149 | + gh pr edit "${PR_NUMBER}" --repo "${REPO}" --remove-label pre-release || true |
0 commit comments