1
+ name : PR Preview
2
+ on :
3
+ pull_request :
4
+ types : [opened, synchronize]
5
+
6
+ jobs :
7
+ preview :
8
+ runs-on : ubuntu-latest
9
+ steps :
10
+ - uses : actions/checkout@v4
11
+ - uses : actions/setup-python@v5
12
+ with :
13
+ python-version : ' 3.x'
14
+
15
+ - name : Set preview version
16
+ run : |
17
+ BASE_VERSION=$(grep -o "__version__.*" socketsecurity/__init__.py | awk '{print $3}' | tr -d "'")
18
+ PREVIEW_VERSION="${BASE_VERSION}.dev${{ github.event.pull_request.number }}${{ github.event.pull_request.commits }}"
19
+ echo "VERSION=${PREVIEW_VERSION}" >> $GITHUB_ENV
20
+
21
+ # Update version in __init__.py
22
+ echo "__version__ = \"${PREVIEW_VERSION}\"" > socketsecurity/__init__.py.tmp
23
+ cat socketsecurity/__init__.py | grep -v "__version__" >> socketsecurity/__init__.py.tmp
24
+ mv socketsecurity/__init__.py.tmp socketsecurity/__init__.py
25
+
26
+ # Verify the change
27
+ echo "Updated version in __init__.py:"
28
+ cat socketsecurity/__init__.py | grep "__version__"
29
+
30
+ - name : Check if version exists on Test PyPI
31
+ id : version_check
32
+ env :
33
+ VERSION : ${{ env.VERSION }}
34
+ run : |
35
+ if curl -s -f https://test.pypi.org/pypi/socketsecurity/$VERSION/json > /dev/null; then
36
+ echo "Version ${VERSION} already exists on Test PyPI"
37
+ echo "exists=true" >> $GITHUB_OUTPUT
38
+ else
39
+ echo "Version ${VERSION} not found on Test PyPI"
40
+ echo "exists=false" >> $GITHUB_OUTPUT
41
+ fi
42
+
43
+ - name : Build package
44
+ if : steps.version_check.outputs.exists != 'true'
45
+ run : |
46
+ pip install build
47
+ python -m build
48
+
49
+ - name : Restore original version
50
+ if : always()
51
+ run : |
52
+ BASE_VERSION=$(echo $VERSION | cut -d'.' -f1-3)
53
+ echo "__version__ = \"${BASE_VERSION}\"" > socketsecurity/__init__.py.tmp
54
+ cat socketsecurity/__init__.py | grep -v "__version__" >> socketsecurity/__init__.py.tmp
55
+ mv socketsecurity/__init__.py.tmp socketsecurity/__init__.py
56
+
57
+ - name : Publish to Test PyPI
58
+ if : steps.version_check.outputs.exists != 'true'
59
+
60
+ with :
61
+ repository-url : https://test.pypi.org/legacy/
62
+ password : ${{ secrets.TEST_PYPI_TOKEN }}
63
+ verbose : true
64
+
65
+ - name : Comment on PR
66
+ if : steps.version_check.outputs.exists != 'true'
67
+ uses : actions/github-script@v7
68
+ env :
69
+ VERSION : ${{ env.VERSION }}
70
+ with :
71
+ script : |
72
+ const version = process.env.VERSION;
73
+ const prNumber = context.payload.pull_request.number;
74
+ const owner = context.repo.owner;
75
+ const repo = context.repo.repo;
76
+ // Find existing bot comments
77
+ const comments = await github.rest.issues.listComments({
78
+ owner: context.repo.owner,
79
+ repo: context.repo.repo,
80
+ issue_number: prNumber,
81
+ });
82
+
83
+ const botComment = comments.data.find(comment =>
84
+ comment.user.type === 'Bot' &&
85
+ comment.body.includes('🚀 Preview package published!')
86
+ );
87
+
88
+ const comment = `
89
+ 🚀 Preview package published!
90
+
91
+ Install with:
92
+ \`\`\`bash
93
+ pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple socketsecurity==${version}
94
+ \`\`\`
95
+
96
+ Docker image: \`socketdev/cli:pr-${prNumber}\`
97
+ `;
98
+
99
+ if (botComment) {
100
+ // Update existing comment
101
+ await github.rest.issues.updateComment({
102
+ owner: owner,
103
+ repo: repo,
104
+ comment_id: botComment.id,
105
+ body: comment
106
+ });
107
+ } else {
108
+ // Create new comment
109
+ await github.rest.issues.createComment({
110
+ owner: owner,
111
+ repo: repo,
112
+ issue_number: prNumber,
113
+ body: comment
114
+ });
115
+ }
116
+
117
+ - name : Verify package is available
118
+ if : steps.version_check.outputs.exists != 'true'
119
+ id : verify_package
120
+ env :
121
+ VERSION : ${{ env.VERSION }}
122
+ run : |
123
+ for i in {1..30}; do
124
+ if pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple socketsecurity==${VERSION}; then
125
+ echo "Package ${VERSION} is now available and installable on Test PyPI"
126
+ pip uninstall -y socketsecurity
127
+ echo "success=true" >> $GITHUB_OUTPUT
128
+ exit 0
129
+ fi
130
+ echo "Attempt $i: Package not yet installable, waiting 20s... (${i}/30)"
131
+ sleep 20
132
+ done
133
+ echo "success=false" >> $GITHUB_OUTPUT
134
+ exit 1
135
+
136
+ - name : Login to Docker Hub
137
+ if : steps.verify_package.outputs.success == 'true'
138
+ uses : docker/login-action@v3
139
+ with :
140
+ username : ${{ secrets.DOCKERHUB_USERNAME }}
141
+ password : ${{ secrets.DOCKERHUB_TOKEN }}
142
+
143
+ - name : Build & Push Docker Preview
144
+ if : steps.verify_package.outputs.success == 'true'
145
+ uses : docker/build-push-action@v5
146
+ env :
147
+ VERSION : ${{ env.VERSION }}
148
+ with :
149
+ push : true
150
+ tags : socketdev/cli:pr-${{ github.event.pull_request.number }}
151
+ build-args : |
152
+ CLI_VERSION=${{ env.VERSION }}
153
+ PIP_INDEX_URL=https://test.pypi.org/simple
154
+ PIP_EXTRA_INDEX_URL=https://pypi.org/simple
0 commit comments