Skip to content

Commit 0794ad4

Browse files
committed
Add conda and pip internal uploads
1 parent 8853637 commit 0794ad4

File tree

6 files changed

+135
-12
lines changed

6 files changed

+135
-12
lines changed

.github/workflows/conda-build.yml

+12
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ on:
2121
description: "GitHub environment in which secrets are stored"
2222
type: string
2323
default: "release"
24+
destination:
25+
description: "Upload packaging index destination"
26+
options:
27+
- anaconda
28+
- internal
29+
type: choice
30+
default: anaconda
2431
secrets:
2532
ANACONDA_TOKEN:
2633
required: true
@@ -49,6 +56,7 @@ jobs:
4956
token-exists:
5057
runs-on: ubuntu-latest
5158
environment: ${{ inputs.environment }}
59+
if: inputs.destination == 'anaconda'
5260
steps:
5361
- name: check if ANACONDA_TOKEN exists
5462
env:
@@ -83,6 +91,10 @@ jobs:
8391
- name: Add conda channel
8492
run: conda config --add channels city-modelling-lab
8593

94+
- name: Add internal conda channel
95+
if: inputs.destination == 'internal'
96+
run: conda config --add channels https://packages.arup.com/conda
97+
8698
- name: Build conda package
8799
run: conda mambabuild ${{ inputs.recipe_dir }}
88100

.github/workflows/conda-upload.yml

+54-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ on:
1919
description: "GitHub environment in which secrets are stored"
2020
type: string
2121
default: "release"
22+
destination:
23+
description: "Upload packaging index destination"
24+
options:
25+
- anaconda
26+
- internal
27+
type: choice
28+
default: anaconda
2229
secrets:
2330
ANACONDA_TOKEN:
2431
required: true
@@ -28,11 +35,12 @@ defaults:
2835
shell: bash -l {0}
2936

3037
jobs:
31-
conda-publish:
38+
conda-anaconda-publish:
39+
if: inputs.destination == 'anaconda'
3240
runs-on: ubuntu-latest
3341
environment: ${{ inputs.environment }}
3442
env:
35-
PACKAGENAME: "conda-build[a-zA-Z0-9-.]*-${{ inputs.package_name }}-${{ inputs.version }}"
43+
ARTIFACTNAME: "conda-build[a-zA-Z0-9-.]*-${{ inputs.package_name }}-${{ inputs.version }}"
3644
steps:
3745
- uses: actions/checkout@v4
3846
- uses: mamba-org/setup-micromamba@v2
@@ -49,7 +57,7 @@ jobs:
4957
if: inputs.build_workflow != ''
5058
uses: dawidd6/action-download-artifact@v7
5159
with:
52-
name: ${{ env.PACKAGENAME }}
60+
name: ${{ env.ARTIFACTNAME }}
5361
name_is_regexp: true
5462
workflow: ${{ inputs.build_workflow }}
5563
path: ${{ runner.temp }}/conda_builds
@@ -58,6 +66,7 @@ jobs:
5866
if: inputs.build_workflow == ''
5967
uses: actions/download-artifact@v4
6068
with:
69+
pattern: ${{ env.ARTIFACTNAME }}
6170
path: ${{ runner.temp }}/conda_builds
6271

6372
- name: Get version without the v
@@ -69,3 +78,45 @@ jobs:
6978
env:
7079
ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_TOKEN }}
7180
run: find ${{ runner.temp }}/conda_builds -path "**/${{ inputs.package_name }}-${{ env.VERSION }}-*.tar.bz2" -exec anaconda upload {} +
81+
82+
conda-internal-publish:
83+
if: inputs.destination == 'internal'
84+
runs-on: [self-hosted, linux, packages]
85+
env:
86+
ARTIFACTNAME: "conda-build[a-zA-Z0-9-.]*-${{ inputs.package_name }}-${{ inputs.version }}"
87+
PACKAGENAME: "conda-build-*-${{ inputs.package_name }}-${{ inputs.version }}"
88+
steps:
89+
- uses: mamba-org/setup-micromamba@v2
90+
with:
91+
micromamba-version: '1.5.10-0'
92+
environment-name: condaindex
93+
create-args: conda-index
94+
post-cleanup: all
95+
cache-environment: true
96+
micromamba-binary-path: ${{ runner.temp }}/bin/micromamba
97+
98+
- name: Download built conda package from another workflow
99+
uses: dawidd6/action-download-artifact@v7
100+
with:
101+
name: ${{ env.ARTIFACTNAME }}
102+
name_is_regexp: true
103+
workflow: ${{ inputs.build_workflow }}
104+
path: ${{ runner.temp }}/conda_builds
105+
106+
- name: Get version without the v
107+
run: |
108+
TAG=${{ inputs.version }}
109+
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
110+
111+
# Move to a location that can be accessed at packages.arup.com
112+
- name: Move package to download location
113+
shell: bash
114+
run: |
115+
touch ${{ runner.temp }}/.condarc
116+
rsync -a -v --prune-empty-dirs --include '*/' --include '${{ inputs.package_name }}-${{ env.VERSION }}-*.tar.bz2' --exclude '*' ${{ runner.temp }}/conda_builds/${{ env.PACKAGENAME }}/ ~/packages/conda/
117+
118+
- name: Re-index conda
119+
env:
120+
CONDARC: ${{ runner.temp }}/.condarc
121+
shell: bash -l {0}
122+
run: python -m conda_index ~/packages/conda

.github/workflows/pip-build.yml

+9-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ on:
2121
required: false
2222
type: string
2323
default: "--no-deps"
24+
destination:
25+
description: "Upload packaging index destination"
26+
options:
27+
- pypi
28+
- internal
29+
type: choice
30+
default: pypi
2431

2532
secrets:
2633
TEST_PYPI_API_TOKEN:
@@ -42,7 +49,7 @@ jobs:
4249
# cannot use secrets directly in conditionals
4350
# see https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#using-secrets-in-a-workflow
4451
test_pypi_token: ${{ secrets.TEST_PYPI_API_TOKEN }}
45-
if: env.test_pypi_token == ''
52+
if: inputs.destination == 'pypi' && env.test_pypi_token == ''
4653
run: |
4754
echo "the secret \"TEST_PYPI_API_TOKEN\" is not available, so the pypi package cannot be uploaded to the test index site."
4855
echo "Please go to \"settings \> secrets \> actions\" to create it before trying to build the pip package."
@@ -98,7 +105,7 @@ jobs:
98105
pip-test-upload: # upload to test-pypi and then check install from there succeeds
99106
needs: [pip-build, pip-test-build]
100107
environment: ${{ inputs.environment }}
101-
if: needs.pip-build.result == 'success' && needs.pip-test-build.result == 'success'
108+
if: needs.pip-build.result == 'success' && needs.pip-test-build.result == 'success' && inputs.destination == 'pypi'
102109
runs-on: ubuntu-latest
103110
steps:
104111
- uses: mamba-org/setup-micromamba@v2

.github/workflows/pip-upload.yml

+42-5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ on:
1919
description: "GitHub environment in which secrets are stored"
2020
type: string
2121
default: "pre-release"
22+
destination:
23+
description: "Upload packaging index destination"
24+
options:
25+
- pypi
26+
- internal
27+
type: choice
28+
default: pypi
2229
secrets:
2330
PYPI_API_TOKEN:
2431
required: true
@@ -28,11 +35,12 @@ defaults:
2835
shell: bash -l {0}
2936

3037
jobs:
31-
pip-publish:
38+
pip-pypi-publish:
3239
runs-on: ubuntu-latest
40+
if: inputs.destination == 'pypi'
3341
environment: ${{ inputs.environment }}
3442
env:
35-
PACKAGENAME: "pip-build-${{ inputs.package_name }}-${{ inputs.version }}"
43+
ARTIFACTNAME: "pip-build-${{ inputs.package_name }}-${{ inputs.version }}"
3644

3745
steps:
3846
- name: check if PYPI_API_TOKEN exists
@@ -50,18 +58,47 @@ jobs:
5058
if: inputs.build_workflow != ''
5159
uses: dawidd6/action-download-artifact@v7
5260
with:
53-
name: ${{ env.PACKAGENAME }}
61+
name: ${{ env.ARTIFACTNAME }}
5462
workflow: ${{ inputs.build_workflow }}
5563
path: dist/
5664

5765
- name: Download built package from same workflow
5866
if: inputs.build_workflow == ''
5967
uses: actions/download-artifact@v4
6068
with:
61-
name: ${{ env.PACKAGENAME }}
69+
name: ${{ env.ARTIFACTNAME }}
6270
path: dist/
6371

6472
- name: Publish distribution 📦 to PyPI
6573
uses: pypa/gh-action-pypi-publish@release/v1
6674
with:
67-
password: ${{ secrets.PYPI_API_TOKEN }}
75+
password: ${{ secrets.PYPI_API_TOKEN }}
76+
77+
78+
pip-internal-publish:
79+
if: inputs.destination == 'internal'
80+
runs-on: [self-hosted, linux, packages]
81+
environment: ${{ inputs.environment }}
82+
env:
83+
ARTIFACTNAME: "pip-build-${{ inputs.package_name }}-${{ inputs.version }}"
84+
85+
steps:
86+
- name: Download built package from another workflow
87+
if: inputs.build_workflow != ''
88+
uses: dawidd6/action-download-artifact@v7
89+
with:
90+
name: ${{ env.ARTIFACTNAME }}
91+
workflow: ${{ inputs.build_workflow }}
92+
path: ${{ runner.temp }}/${{ env.ARTIFACTNAME }}/
93+
94+
- name: Download built package from same workflow
95+
if: inputs.build_workflow == ''
96+
uses: actions/download-artifact@v4
97+
with:
98+
name: ${{ env.ARTIFACTNAME }}
99+
path: ${{ runner.temp }}/${{ env.ARTIFACTNAME }}/
100+
101+
- name: Publish distribution 📦 to internal repository
102+
run: |
103+
cp ${{ runner.temp }}/${{ env.ARTIFACTNAME }}/${{ inputs.package_name }}-*.tar.gz ~/packages/
104+
cp ${{ runner.temp }}/${{ env.ARTIFACTNAME }}/${{ inputs.package_name }}-*.tar.gz ~/packages/${{ inputs.package_name }}.tar.gz

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3333

3434
### Added
3535

36+
- Ability to upload pip / conda packages to <https://packages.arup.com> for internal Arup projects.
3637
- Composite action for building a project-specific conda environment, used across reusable workflows but also available for direct use as a step in other projects (#26).
3738
- Environment cache directory within the runner working directory (`.cache/envs`) (#29).
3839

39-
4040
## [v1.0.0] - 2024-07-12
4141

4242
### Fixed

README.md

+17-1
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,12 @@ _Inputs_:
146146
- environment (optional, default="pre-release"): GitHub environment in which secrets are stored.
147147
Environments help to ensure that only certain operations are available to different user types.
148148
E.g., releasing packages can be given an extra layer of security whereby a maintainer has to approve an action before it can run.
149+
- destination (optional, default="anaconda"): One of "anaconda" or "internal", to specify what the ultimate destination of the package will be.
150+
If `internal`, the package will be uploaded to <https://packages.arup.com/conda>.
151+
If `anaconda`, the package will be uploaded to <https://anaconda.org/[CHANNEL-NAME]/> where `[CHANNEL-NAME]` is linked to the `ANACONDA_TOKEN` secret.
149152

150153
_Required secrets_: `ANACONDA_TOKEN` (required to verify that later upload will not fail) stored in a GitHub actions environment of the same name as `environment`.
154+
If `destination=internal`, this secret must still be defined, but can be a placeholder string (e.g. "NA").
151155

152156
### Upload a conda package
153157

@@ -164,8 +168,12 @@ _Inputs_:
164168
- environment (optional, default="pre-release"): GitHub environment in which secrets are stored.
165169
Environments help to ensure that only certain operations are available to different user types.
166170
E.g., releasing packages can be given an extra layer of security whereby a maintainer has to approve an action before it can run.
171+
- destination (optional, default="anaconda"): One of "anaconda" or "internal", to specify what the ultimate destination of the package will be.
172+
If `internal`, the package will be uploaded to <https://packages.arup.com/conda>.
173+
If `anaconda`, the package will be uploaded to <https://anaconda.org/[CHANNEL-NAME]/> where `[CHANNEL-NAME]` is linked to the `ANACONDA_TOKEN` secret.
167174

168175
_Required secrets_: `ANACONDA_TOKEN` stored in a GitHub actions environment of the same name as `environment`.
176+
If `destination=internal`, this secret must still be defined, but can be a placeholder string (e.g. "NA").
169177

170178
### Build a pip package for upload to PyPI
171179

@@ -187,8 +195,12 @@ E.g., releasing packages can be given an extra layer of security whereby a maint
187195
- pip_args (optional, default="--no-deps"). Any arguments to pass to pip when running test installations.
188196
Many of our packages have non-python dependencies, so it is useful to use `--no-deps` in the installation.
189197
However, if you know that your library has purely python dependencies then the pip build process is made more robust by removing this argument (i.e. `pip_args: ""`)
198+
- destination (optional, default="pypi"): One of "pypi" or "internal", to specify what the ultimate destination of the package will be.
199+
If `internal`, the package will be uploaded to <https://packages.arup.com>.
200+
If `pypi`, the package will be uploaded to <https://test.pypi.org/> for testing and <https://pypi.org/> for final upload.
190201

191202
_Required secrets_: `TEST_PYPI_API_TOKEN` stored in a GitHub actions environment of the same name as `environment`.
203+
If `destination=internal`, this secret must still be defined, but can be a placeholder string (e.g. "NA").
192204

193205
### Upload a pip package to PyPI
194206

@@ -205,8 +217,12 @@ _Inputs_:
205217
- environment (optional, default="pre-release"): GitHub environment in which secrets are stored.
206218
Environments help to ensure that only certain operations are available to different user types.
207219
E.g., releasing packages can be given an extra layer of security whereby a maintainer has to approve an action before it can run.
220+
- destination (optional, default="pypi"): One of "pypi" or "internal", to specify what the ultimate destination of the package will be.
221+
If `internal`, the package will be uploaded to <https://packages.arup.com>.
222+
If `pypi`, the package will be uploaded to <https://test.pypi.org/> for testing and <https://pypi.org/> for final upload.
208223

209224
_Required secrets_: `PYPI_API_TOKEN` stored in a GitHub actions environment of the same name as `environment`.
225+
If `destination=internal`, this secret must still be defined, but can be a placeholder string (e.g. "NA").
210226

211227
### Deploy documentation
212228

@@ -296,4 +312,4 @@ _Required secrets_: `SLACK_WEBHOOK`
296312

297313
_URL_: `arup-group/actions-city-modelling-lab/.github/workflows/template-check.yml`
298314

299-
_description_: If your project was generated using a [cookiecutter](https://github.com/cookiecutter/cookiecutter) template, check whether there are changes to the template that could be pulled into the project.
315+
_description_: If your project was generated using a [cookiecutter](https://github.com/cookiecutter/cookiecutter) template, check whether there are changes to the template that could be pulled into the project.

0 commit comments

Comments
 (0)