|
1 | | -name: Releasing PR |
| 1 | +name: "Pull Request & Release" |
2 | 2 |
|
3 | 3 | on: |
4 | 4 | pull_request: |
5 | | - types: [labeled, opened, synchronize, reopened, closed] |
| 5 | + types: [closed] |
6 | 6 |
|
| 7 | +# Cancel in‑flight runs for the same PR when a new push arrives. |
7 | 8 | concurrency: |
8 | | - group: pull-requests-release-${{ github.workflow }}-${{ github.event.pull_request.number }} |
| 9 | + group: pr-${{ github.workflow }}-${{ github.event.pull_request.number }} |
9 | 10 | cancel-in-progress: true |
10 | 11 |
|
11 | 12 | jobs: |
12 | | - prepare_env: |
13 | | - name: Prepare environment |
14 | | - runs-on: [self-hosted] |
15 | | - permissions: |
16 | | - contents: read |
17 | | - packages: write |
18 | | - |
19 | | - if: | |
20 | | - contains(github.event.pull_request.labels.*.name, 'release') && |
21 | | - github.event.action != 'closed' |
22 | | -
|
23 | | - steps: |
24 | | - - name: Checkout code |
25 | | - uses: actions/checkout@v4 |
26 | | - with: |
27 | | - fetch-depth: 0 |
28 | | - fetch-tags: true |
29 | | - |
30 | | - - name: Login to GitHub Container Registry |
31 | | - uses: docker/login-action@v3 |
32 | | - with: |
33 | | - username: ${{ github.repository_owner }} |
34 | | - password: ${{ secrets.GITHUB_TOKEN }} |
35 | | - registry: ghcr.io |
36 | | - |
37 | | - - name: Extract tag from PR branch |
38 | | - id: get_tag |
39 | | - uses: actions/github-script@v7 |
40 | | - with: |
41 | | - script: | |
42 | | - const branch = context.payload.pull_request.head.ref; |
43 | | - const m = branch.match(/^release-(\d+\.\d+\.\d+(?:[-\w\.]+)?)$/); |
44 | | - if (!m) { |
45 | | - core.setFailed(`❌ Branch '${branch}' does not match 'release-X.Y.Z[-suffix]'`); |
46 | | - return; |
47 | | - } |
48 | | - const tag = `v${m[1]}`; |
49 | | - core.setOutput('tag', tag); |
50 | | -
|
51 | | - - name: Find draft release and get asset IDs |
52 | | - id: fetch_assets |
53 | | - uses: actions/github-script@v7 |
54 | | - with: |
55 | | - github-token: ${{ secrets.GH_PAT }} |
56 | | - script: | |
57 | | - const tag = '${{ steps.get_tag.outputs.tag }}'; |
58 | | - const releases = await github.rest.repos.listReleases({ |
59 | | - owner: context.repo.owner, |
60 | | - repo: context.repo.repo, |
61 | | - per_page: 100 |
62 | | - }); |
63 | | - const draft = releases.data.find(r => r.tag_name === tag && r.draft); |
64 | | - if (!draft) { |
65 | | - core.setFailed(`Draft release '${tag}' not found`); |
66 | | - return; |
67 | | - } |
68 | | - const findAssetId = (name) => |
69 | | - draft.assets.find(a => a.name === name)?.id; |
70 | | - const installerId = findAssetId("cozystack-installer.yaml"); |
71 | | - const diskId = findAssetId("nocloud-amd64.raw.xz"); |
72 | | - if (!installerId || !diskId) { |
73 | | - core.setFailed("Missing required assets"); |
74 | | - return; |
75 | | - } |
76 | | - core.setOutput("installer_id", installerId); |
77 | | - core.setOutput("disk_id", diskId); |
78 | | - |
79 | | - - name: Download assets from GitHub API |
80 | | - run: | |
81 | | - mkdir -p _out/assets |
82 | | - curl -sSL \ |
83 | | - -H "Authorization: token ${GH_PAT}" \ |
84 | | - -H "Accept: application/octet-stream" \ |
85 | | - -o _out/assets/cozystack-installer.yaml \ |
86 | | - "https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/assets/${{ steps.fetch_assets.outputs.installer_id }}" |
87 | | - curl -sSL \ |
88 | | - -H "Authorization: token ${GH_PAT}" \ |
89 | | - -H "Accept: application/octet-stream" \ |
90 | | - -o _out/assets/nocloud-amd64.raw.xz \ |
91 | | - "https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/assets/${{ steps.fetch_assets.outputs.disk_id }}" |
92 | | - env: |
93 | | - GH_PAT: ${{ secrets.GH_PAT }} |
94 | | - |
95 | | - - name: Set sandbox ID |
96 | | - run: echo "SANDBOX_NAME=cozy-e2e-sandbox-$(echo "${GITHUB_REPOSITORY}:${GITHUB_WORKFLOW}:${GITHUB_REF}" | sha256sum | cut -c1-10)" >> $GITHUB_ENV |
97 | | - |
98 | | - - name: Prepare workspace |
99 | | - run: | |
100 | | - cd .. |
101 | | - rm -rf /tmp/$SANDBOX_NAME |
102 | | - cp -r cozystack /tmp/$SANDBOX_NAME |
103 | | - sudo systemctl stop "rm-workspace-$SANDBOX_NAME.timer" "rm-workspace-$SANDBOX_NAME.service" 2>/dev/null || true |
104 | | - sudo systemctl reset-failed "rm-workspace-$SANDBOX_NAME.timer" "rm-workspace-$SANDBOX_NAME.service" 2>/dev/null || true |
105 | | - sudo systemctl daemon-reexec |
106 | | - sudo systemd-run \ |
107 | | - --on-calendar="$(date -d 'now + 24 hours' '+%Y-%m-%d %H:%M:%S')" \ |
108 | | - --unit=rm-workspace-$SANDBOX_NAME \ |
109 | | - rm -rf /tmp/$SANDBOX_NAME |
110 | | -
|
111 | | - - name: Delete sandbox in 24h |
112 | | - run: | |
113 | | - sudo systemctl stop "teardown-$SANDBOX_NAME.timer" "teardown-$SANDBOX_NAME.service" 2>/dev/null || true |
114 | | - sudo systemctl reset-failed "teardown-$SANDBOX_NAME.timer" "teardown-$SANDBOX_NAME.service" 2>/dev/null || true |
115 | | - sudo systemctl daemon-reexec |
116 | | - sudo systemd-run \ |
117 | | - --on-calendar="$(date -d 'now + 24 hours' '+%Y-%m-%d %H:%M:%S')" \ |
118 | | - --unit=teardown-$SANDBOX_NAME \ |
119 | | - /usr/bin/docker rm -f $SANDBOX_NAME |
120 | | -
|
121 | | - - name: Prepare environment |
122 | | - run: | |
123 | | - cd /tmp/$SANDBOX_NAME |
124 | | - make SANDBOX_NAME=$SANDBOX_NAME prepare-env |
125 | | -
|
126 | | - install_cozystack: |
127 | | - name: Install Cozystack |
128 | | - runs-on: [self-hosted] |
129 | | - needs: prepare_env |
130 | | - permissions: |
131 | | - contents: read |
132 | | - packages: write |
133 | | - if: | |
134 | | - contains(github.event.pull_request.labels.*.name, 'release') && |
135 | | - github.event.action != 'closed' |
136 | | -
|
137 | | - steps: |
138 | | - - name: Set sandbox ID |
139 | | - run: echo "SANDBOX_NAME=cozy-e2e-sandbox-$(echo "${GITHUB_REPOSITORY}:${GITHUB_WORKFLOW}:${GITHUB_REF}" | sha256sum | cut -c1-10)" >> $GITHUB_ENV |
140 | | - |
141 | | - - name: Install Cozystack |
142 | | - run: | |
143 | | - cd /tmp/$SANDBOX_NAME |
144 | | - make -C packages/core/testing SANDBOX_NAME=$SANDBOX_NAME install-cozystack |
145 | | -
|
146 | | - setup_tenant: |
147 | | - name: Setup tenant-test |
148 | | - runs-on: [self-hosted] |
149 | | - needs: install_cozystack |
150 | | - permissions: |
151 | | - contents: read |
152 | | - packages: write |
153 | | - if: | |
154 | | - contains(github.event.pull_request.labels.*.name, 'release') && |
155 | | - github.event.action != 'closed' |
156 | | -
|
157 | | - steps: |
158 | | - - name: Set sandbox ID |
159 | | - run: echo "SANDBOX_NAME=cozy-e2e-sandbox-$(echo "${GITHUB_REPOSITORY}:${GITHUB_WORKFLOW}:${GITHUB_REF}" | sha256sum | cut -c1-10)" >> $GITHUB_ENV |
160 | | - |
161 | | - |
162 | | - - name: E2E Apps |
163 | | - run: | |
164 | | - cd /tmp/$SANDBOX_NAME |
165 | | - make -C packages/core/testing SANDBOX_NAME=$SANDBOX_NAME test-apps-tenant |
166 | | -
|
167 | | - test_apps: |
168 | | - strategy: |
169 | | - matrix: |
170 | | - app: [clickhouse,kubernetes,mysql,postgres,virtualmachine,vminstance] |
171 | | - name: Test ${{ matrix.app }} |
172 | | - runs-on: [self-hosted] |
173 | | - needs: setup_tenant |
174 | | - permissions: |
175 | | - contents: read |
176 | | - packages: write |
177 | | - if: | |
178 | | - contains(github.event.pull_request.labels.*.name, 'release') && |
179 | | - github.event.action != 'closed' |
180 | | -
|
181 | | - steps: |
182 | | - - name: Set sandbox ID |
183 | | - run: echo "SANDBOX_NAME=cozy-e2e-sandbox-$(echo "${GITHUB_REPOSITORY}:${GITHUB_WORKFLOW}:${GITHUB_REF}" | sha256sum | cut -c1-10)" >> $GITHUB_ENV |
184 | | - |
185 | | - - name: E2E Apps |
186 | | - run: | |
187 | | - cd /tmp/$SANDBOX_NAME |
188 | | - make -C packages/core/testing SANDBOX_NAME=$SANDBOX_NAME test-apps-${{ matrix.app }} |
189 | | -
|
190 | | - cleanup: |
191 | | - name: Tear down environment |
192 | | - runs-on: [self-hosted] |
193 | | - needs: test_apps |
194 | | - permissions: |
195 | | - contents: read |
196 | | - packages: write |
197 | | - if: | |
198 | | - contains(github.event.pull_request.labels.*.name, 'release') && |
199 | | - github.event.action != 'closed' |
200 | | -
|
201 | | - steps: |
202 | | - - name: Checkout code |
203 | | - uses: actions/checkout@v4 |
204 | | - with: |
205 | | - fetch-depth: 0 |
206 | | - fetch-tags: true |
207 | | - |
208 | | - - name: Set sandbox ID |
209 | | - run: echo "SANDBOX_NAME=cozy-e2e-sandbox-$(echo "${GITHUB_REPOSITORY}:${GITHUB_WORKFLOW}:${GITHUB_REF}" | sha256sum | cut -c1-10)" >> $GITHUB_ENV |
210 | | - |
211 | | - |
212 | | - - name: Tear down sandbox |
213 | | - run: make -C packages/core/testing SANDBOX_NAME=$SANDBOX_NAME delete |
214 | | - |
215 | | - - name: Remove workspace |
216 | | - run: rm -rf /tmp/$SANDBOX_NAME |
217 | | - |
218 | | - - name: Tear down timers |
219 | | - run: | |
220 | | - sudo systemctl stop "rm-workspace-$SANDBOX_NAME.timer" "rm-workspace-$SANDBOX_NAME.service" 2>/dev/null || true |
221 | | - sudo systemctl reset-failed "rm-workspace-$SANDBOX_NAME.timer" "rm-workspace-$SANDBOX_NAME.service" 2>/dev/null || true |
222 | | - sudo systemctl stop "teardown-$SANDBOX_NAME.timer" "teardown-$SANDBOX_NAME.service" 2>/dev/null || true |
223 | | - sudo systemctl reset-failed "teardown-$SANDBOX_NAME.timer" "teardown-$SANDBOX_NAME.service" 2>/dev/null || true |
224 | | - sudo systemctl daemon-reexec |
225 | | -
|
226 | 13 | finalize: |
227 | 14 | name: Finalize Release |
228 | 15 | runs-on: [self-hosted] |
|
0 commit comments