Create package: add GH token #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Create package | ||
on: | ||
workflow_call: | ||
inputs: | ||
skip_checks: | ||
description: Value `true` will skip version checks, use for testing or in nightly builds. | ||
type: boolean | ||
required: false | ||
build_config: | ||
description: | ||
Path to build configuration yaml. Relative path from the repository root, | ||
e.g. `.github/build-config.yml`. | ||
required: false | ||
default: ".github/ci-config.yml" | ||
type: string | ||
cpack_options: | ||
description: CPack options to be used on all platforms. | ||
type: string | ||
required: false | ||
cpack_options_deb: | ||
description: CPack options for DEB generator | ||
type: string | ||
required: false | ||
cpack_options_rpm: | ||
description: CPack options for RPM generator | ||
type: string | ||
required: false | ||
restrict_matrix_jobs: | ||
description: list of matrix jobs to restrict to | ||
type: string | ||
required: false | ||
secrets: | ||
github_token: | ||
description: GitHub token | ||
required: false | ||
url_debian_11: | ||
description: Use other than the default url for Debian 11. | ||
required: false | ||
token_debian_11: | ||
description: Use other than the default token for Debian 11. | ||
required: false | ||
url_debian_12: | ||
description: Use other than the default url for Debian 12. | ||
required: false | ||
token_debian_12: | ||
description: Use other than the default token for Debian 12. | ||
required: false | ||
url_rocky_8: | ||
description: Use other than the default url for Rocky 8. | ||
required: false | ||
token_rocky_8: | ||
description: Use other than the default token for Rocky 8. | ||
required: false | ||
url_rocky_9: | ||
description: Use other than the default url for Rocky 9. | ||
required: false | ||
token_rocky_9: | ||
description: Use other than the default token for Rocky 9. | ||
required: false | ||
jobs: | ||
check: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: "0" | ||
- name: Test tag name pattern | ||
if: ${{ ! inputs.skip_checks }} | ||
shell: python | ||
run: | | ||
import re | ||
import sys | ||
tag_pattern = r"${{ vars.TAG_REGEX_FOR_DEPLOYMENT }}" | ||
ref = "${{ github.ref_name }}" | ||
if not tag_pattern: | ||
sys.exit(0) | ||
if not re.match(tag_pattern, ref): | ||
print(f"::error::{ref} does not match {tag_pattern}") | ||
sys.exit(1) | ||
- name: Test branch name pattern | ||
if: ${{ vars.BRANCH_REGEX_FOR_DEPLOYMENT != '' && (! inputs.skip_checks) }} | ||
run: | | ||
git branch --all --list --format "%(refname:lstrip=-1)" --contains "${{ github.ref_name }}" | grep -E "${{ vars.BRANCH_REGEX_FOR_DEPLOYMENT }}" | ||
setup: | ||
name: setup | ||
runs-on: ubuntu-24.04 | ||
outputs: | ||
matrix: ${{ steps.set-matrix.outputs.matrix }} | ||
steps: | ||
- name: Set Matrix | ||
id: set-matrix | ||
shell: bash -eux {0} | ||
run: | | ||
MATRIX=$(cat << 'EOS' | ||
name: | ||
- gnu@debian-11 | ||
- gnu@debian-12 | ||
- [email protected] | ||
- [email protected] | ||
include: | ||
- name: gnu@debian-11 | ||
labels: [self-hosted, platform-builder-debian-11] | ||
os: debian-11 | ||
compiler: gnu | ||
compiler_cc: gcc | ||
compiler_cxx: g++ | ||
compiler_fc: gfortran | ||
cpack_generator: DEB | ||
cpack_options: > | ||
-D [email protected] | ||
-D CPACK_PACKAGING_INSTALL_PREFIX=/opt/ecmwf | ||
-DCPACK_DEBIAN_PACKAGE_SHLIBDEPS=ON ${{ inputs.cpack_options_deb }} | ||
upload_token: NEXUS_TEST_REPO_UPLOAD_TOKEN | ||
upload_url: NEXUS_TEST_REPO_URL_DEBIAN_11 | ||
- name: gnu@debian-12 | ||
labels: [self-hosted, platform-builder-debian-12] | ||
os: debian-12 | ||
compiler: gnu | ||
compiler_cc: gcc | ||
compiler_cxx: g++ | ||
compiler_fc: gfortran | ||
cpack_generator: DEB | ||
cpack_options: > | ||
-D [email protected] | ||
-D CPACK_PACKAGING_INSTALL_PREFIX=/opt/ecmwf | ||
-DCPACK_DEBIAN_PACKAGE_SHLIBDEPS=ON ${{ inputs.cpack_options_deb }} | ||
upload_token: NEXUS_TEST_REPO_UPLOAD_TOKEN | ||
upload_url: NEXUS_TEST_REPO_URL_DEBIAN_12 | ||
- name: [email protected] | ||
labels: [self-hosted, platform-builder-rocky-8.6] | ||
os: rocky-8.6 | ||
compiler: gnu | ||
compiler_cc: gcc | ||
compiler_cxx: g++ | ||
compiler_fc: gfortran | ||
cpack_generator: RPM | ||
cpack_options: > | ||
-D CPACK_PACKAGING_INSTALL_PREFIX=/opt/ecmwf | ||
${{ inputs.cpack_options_rpm }} | ||
upload_token: NEXUS_TEST_REPO_UPLOAD_TOKEN | ||
upload_url: NEXUS_TEST_REPO_URL_ROCKY_8 | ||
- name: [email protected] | ||
labels: [self-hosted, platform-builder-rocky-9.5] | ||
os: rocky-9.5 | ||
compiler: gnu | ||
compiler_cc: gcc | ||
compiler_cxx: g++ | ||
compiler_fc: gfortran | ||
cpack_generator: RPM | ||
cpack_options: > | ||
-D CPACK_PACKAGING_INSTALL_PREFIX=/opt/ecmwf | ||
${{ inputs.cpack_options_rpm }} | ||
upload_token: NEXUS_TEST_REPO_UPLOAD_TOKEN | ||
upload_url: NEXUS_TEST_REPO_URL_ROCKY_9 | ||
EOS | ||
) | ||
RESTRICT_MATRIX_JOBS=$(cat << 'EOS' | ||
${{ inputs.restrict_matrix_jobs }} | ||
EOS | ||
) | ||
echo "MATRIX:" | ||
echo $MATRIX | ||
SELECT_NAME_COND="1 != 1" | ||
SELECT_INCLUDE_COND="1 != 1" | ||
for restrict_job in $RESTRICT_MATRIX_JOBS; do SELECT_NAME_COND="$SELECT_NAME_COND or . != \"$restrict_job\""; SELECT_INCLUDE_COND="$SELECT_INCLUDE_COND or .name != \"$restrict_job\""; done | ||
echo matrix=$(echo "$MATRIX" | yq eval "del(.name[] | select($SELECT_NAME_COND)) | del(.include[] | select($SELECT_INCLUDE_COND))" --output-format json --indent 0 -) >> $GITHUB_OUTPUT | ||
echo "GITHUB_OUTPUT:" | ||
echo $GITHUB_OUTPUT | ||
deploy: | ||
if: ${{ github.ref_type == 'tag' || inputs.skip_checks }} | ||
needs: [check, setup] | ||
strategy: | ||
fail-fast: false | ||
matrix: ${{ fromJson(needs.setup.outputs.matrix) }} | ||
runs-on: ${{ matrix.labels }} | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Check version number | ||
if: ${{ !inputs.skip_checks }} | ||
shell: python3 {0} | ||
run: | | ||
import os | ||
import re | ||
import sys | ||
tag = "${{ github.ref_name }}" | ||
def check_version(): | ||
file_name = "VERSION" | ||
if os.path.isfile(file_name): | ||
with open(file_name, 'r') as f: | ||
version = f.read().strip() | ||
return version | ||
else: | ||
print(f"::warning::{file_name} file not found! Using {file_name} is the preferred method.") | ||
return | ||
def check_cmakelists(): | ||
file_name = "CMakeLists.txt" | ||
if os.path.isfile(file_name): | ||
with open(file_name, 'r') as f: | ||
content = f.read() | ||
pattern = r"project\([\s\w]+VERSION\s+((?:\d+)(?:.\d+){0,3})" | ||
hit = re.search(pattern, content) | ||
version = hit.group(1) | ||
return version | ||
else: | ||
print(f"::warning::{file_name} file not found!") | ||
return | ||
version = check_version() or check_cmakelists() | ||
if not version: | ||
print("::error::Version not found!") | ||
sys.exit(1) | ||
if version != tag: | ||
print(f"::error::Git tag ({tag}) and project version ({version}) do not match!") | ||
sys.exit(1) | ||
print("OK: Git tag and project versions match.") | ||
- name: Create package | ||
id: build | ||
uses: ecmwf/reusable-workflows/build-package-with-config@v2 | ||
with: | ||
repository: ${{ format('{0}@{1}', github.repository, github.sha ) }} | ||
build_package_inputs: | | ||
repository: ${{ format('{0}@{1}', github.repository, github.sha ) }} | ||
cpack_generator: ${{ matrix.cpack_generator }} | ||
cpack_options: ${{ matrix.cpack_options }} ${{ inputs.cpack_options }} | ||
force_build: true | ||
recreate_cache: true | ||
save_cache: false | ||
self_test: false | ||
build_config: ${{ inputs.build_config }} | ||
github_token: ${{ inputs.github_token || secrets.GH_REPO_READ_TOKEN }} | ||
- name: Upload binary as artifact | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: ${{ matrix.os }} | ||
path: ${{ steps.build.outputs.package_path }} | ||
retention-days: 3 | ||
- name: Upload | ||
run: | | ||
if [ -z "${{ steps.build.outputs.package_path }}" ] || [ ! -f ${{ steps.build.outputs.package_path }} ]; then | ||
echo "::error::Built package not found!" | ||
exit 1 | ||
fi | ||
os=${{ matrix.os }} | ||
token="" | ||
url="" | ||
case "$os" in | ||
"debian-11") | ||
token=${{ secrets.token_debian_11 || secrets[matrix.upload_token] }} | ||
url=${{ secrets.url_debian_11 || secrets[matrix.upload_url] }} | ||
;; | ||
"debian-12") | ||
token=${{ secrets.token_debian_12 || secrets[matrix.upload_token] }} | ||
url=${{ secrets.url_debian_12 || secrets[matrix.upload_url] }} | ||
;; | ||
"rocky-8.6") | ||
token=${{ secrets.token_rocky_8 || secrets[matrix.upload_token] }} | ||
url=${{ secrets.url_rocky_8 || secrets[matrix.upload_url] }} | ||
;; | ||
"rocky-9.5") | ||
token=${{ secrets.token_rocky_9 || secrets[matrix.upload_token] }} | ||
url=${{ secrets.url_rocky_9 || secrets[matrix.upload_url] }} | ||
;; | ||
*) | ||
token=${{ secrets[matrix.upload_token] }} | ||
url=${{ secrets[matrix.upload_url] }} | ||
;; | ||
esac | ||
if [ -z "$token" ]; then | ||
echo "::warning::No upload token provided, skipping upload for $os" | ||
exit 0 | ||
fi | ||
if [ "${{ matrix.cpack_generator }}" == "DEB" ]; then | ||
response=$(curl -w "%{http_code}" --user "$token" -H "Content-Type: multipart/form-data" --data-binary "@${{ steps.build.outputs.package_path }}" "$url") | ||
elif [ "${{ matrix.cpack_generator }}" == "RPM" ]; then | ||
file_name=$(basename "${{ steps.build.outputs.package_path }}") | ||
response=$(curl -w "%{http_code}" --user "$token" --upload-file ${{ steps.build.outputs.package_path }} $url/$file_name) | ||
fi | ||
status=$(echo $response | tail -c 4) | ||
if [ $status -eq 201 ] || [ $status -eq 200 ]; then | ||
echo "Successfully uploaded!" | ||
else | ||
echo "$status: Upload failed" | ||
exit 1 | ||
fi |