From 3f861bdaafaeb6a2398100ccefd4527eeb339e4f Mon Sep 17 00:00:00 2001 From: Iain Sproat <68657+iainsproat@users.noreply.github.com> Date: Fri, 3 Oct 2025 14:39:20 +0100 Subject: [PATCH] ci(release): publish to DockerHub or GHCR based on current repository (#5607) --- .github/workflows/npm.yml | 35 ++++++++++++--- .github/workflows/pull-request.yml | 2 +- .github/workflows/release.yml | 69 +++++++++++++++++++++--------- packages/server/package.json | 4 +- 4 files changed, 80 insertions(+), 30 deletions(-) diff --git a/.github/workflows/npm.yml b/.github/workflows/npm.yml index bceff02da..82e0e081c 100644 --- a/.github/workflows/npm.yml +++ b/.github/workflows/npm.yml @@ -1,6 +1,18 @@ on: workflow_call: inputs: + GITHUB_REGISTRY_URL: + required: true + type: string + GITHUB_ORG: + required: true + type: string + NPM_REGISTRY_URL: + required: true + type: string + NPM_PUBLISH_ACCESS: + required: true + type: string IMAGE_VERSION_TAG: required: true type: string @@ -13,8 +25,12 @@ jobs: name: Publish to npm runs-on: blacksmith-4vcpu-ubuntu-2404 env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + GITHUB_REGISTRY_URL: ${{ inputs.GITHUB_REGISTRY_URL }} + GITHUB_ORG: ${{ inputs.GITHUB_ORG }} + NPM_REGISTRY_URL: ${{ inputs.NPM_REGISTRY_URL }} + NPM_PUBLISH_ACCESS: ${{ inputs.NPM_PUBLISH_ACCESS }} IMAGE_VERSION_TAG: ${{ inputs.IMAGE_VERSION_TAG }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} steps: - uses: actions/checkout@v4.2.2 with: @@ -25,15 +41,22 @@ jobs: cache: yarn - name: Install hardened (no HARD flag) run: PUPPETEER_SKIP_DOWNLOAD=true PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 yarn --immutable - - name: Auth to npm as Speckle + - name: Auth to npm run: | - echo "npmRegistryServer: https://registry.npmjs.org/" >> .yarnrc.yml - echo "npmAuthToken: $NPM_TOKEN" >> .yarnrc.yml + echo "npmRegistryServer: ${NPM_REGISTRY_URL}" >> .yarnrc.yml + echo "npmAuthToken: ${NPM_TOKEN}" >> .yarnrc.yml + echo "npmPublishAccess: ${NPM_PUBLISH_ACCESS}" >> .yarnrc.yml - name: Try login to npm run: yarn npm whoami + - name: Amend package name & git repository to match + # required as per https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry#publishing-a-package-using-a-local-npmrc-file + run: | + if [ "${NPM_REGISTRY_URL}" != "https://registry.npmjs.org/" ]; then + yarn workspaces foreach -tvW --no-private exec "jq '.name |= sub(\"@speckle\"; \"${GITHUB_ORG}\"), .repository.url = \"${GITHUB_REGISTRY_URL}\"' package.json > tmp.json && mv tmp.json package.json" + fi - name: Build public packages run: yarn workspaces foreach -ptvW --no-private run build - name: Bump all versions - run: yarn workspaces foreach -tvW version $IMAGE_VERSION_TAG + run: yarn workspaces foreach -tvW version ${IMAGE_VERSION_TAG} - name: publish to npm - run: 'yarn workspaces foreach -pvW --no-private npm publish --access public' + run: 'yarn workspaces foreach -pvW --no-private npm publish --access ${NPM_PUBLISH_ACCESS}' diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index aad1d0ad0..983cd0396 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -24,7 +24,7 @@ jobs: IMAGE_VERSION_TAG: ${{ needs.get-version.outputs.IMAGE_VERSION_TAG }} REGISTRY_DOMAIN: 'ghcr.io' REGISTRY_USERNAME: ${{ github.actor }} - # REGISTRY_DOMAIN, REGISTRY_USERNAME, REGISTRY_TOKEN must allow pushing to the below IMAGE_PREFIX + # REGISTRY_DOMAIN, REGISTRY_USERNAME, REGISTRY_TOKEN must be configured to match the below IMAGE_PREFIX IMAGE_PREFIX: 'ghcr.io/specklesystems' PUBLISH: false # do not publish the sourcemaps or include the version in frontend-2 builds for pull requests secrets: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c30618d1c..eba902a30 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -36,27 +36,27 @@ jobs: uses: ./.github/workflows/builds.yml with: IMAGE_VERSION_TAG: ${{ needs.get-version.outputs.IMAGE_VERSION_TAG }} - REGISTRY_DOMAIN: 'docker.io' - REGISTRY_USERNAME: 'speckledevops' + REGISTRY_DOMAIN: ${{ (github.repository == 'specklesystems/speckle-server') && 'docker.io' || 'ghcr.io' }} + REGISTRY_USERNAME: ${{ (github.repository == 'specklesystems/speckle-server') && 'speckledevops' || github.actor }} # REGISTRY_DOMAIN, REGISTRY_USERNAME, REGISTRY_TOKEN must allow pushing to the below IMAGE_PREFIX - IMAGE_PREFIX: 'speckle' # without an explicit host, Docker defaults to pushing Docker Hub + IMAGE_PREFIX: ${{ (github.repository == 'specklesystems/speckle-server') && 'speckle' || 'ghcr.io/specklesystems' }} PUBLISH: true # publish the sourcemaps and include the version in frontend-2 builds PUBLISH_LATEST: ${{ startsWith(github.ref, 'refs/heads/main') }} secrets: DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }} - REGISTRY_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + REGISTRY_TOKEN: ${{ (github.repository == 'specklesystems/speckle-server') && secrets.DOCKERHUB_TOKEN || secrets.GITHUB_TOKEN }} - # Temporary duplicate of builds job to push to ghcr.io + #HACK temporary job to build and push to ghcr.io until we migrate everything builds-ghcr: needs: [get-version] uses: ./.github/workflows/builds.yml with: IMAGE_VERSION_TAG: ${{ needs.get-version.outputs.IMAGE_VERSION_TAG }} - REGISTRY_DOMAIN: 'ghcr.io' + REGISTRY_DOMAIN: ${{ 'ghcr.io' }} REGISTRY_USERNAME: ${{ github.actor }} # REGISTRY_DOMAIN, REGISTRY_USERNAME, REGISTRY_TOKEN must allow pushing to the below IMAGE_PREFIX - IMAGE_PREFIX: 'ghcr.io/specklesystems' - PUBLISH: true # do not publish the sourcemaps or include the version in frontend-2 builds for pull requests + IMAGE_PREFIX: ${{ 'ghcr.io/specklesystems' }} + PUBLISH: true # publish the sourcemaps and include the version in frontend-2 builds PUBLISH_LATEST: ${{ startsWith(github.ref, 'refs/heads/main') }} secrets: DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }} @@ -67,38 +67,65 @@ jobs: uses: ./.github/workflows/deployment-tests.yml with: IMAGE_VERSION_TAG: ${{ needs.get-version.outputs.IMAGE_VERSION_TAG }} - REGISTRY_DOMAIN: 'ghcr.io' - REGISTRY_USERNAME: ${{ github.actor }} - IMAGE_PREFIX: 'ghcr.io/specklesystems' + REGISTRY_DOMAIN: ${{ (github.repository == 'specklesystems/speckle-server') && 'docker.io' || 'ghcr.io' }} + REGISTRY_USERNAME: ${{ (github.repository == 'specklesystems/speckle-server') && 'speckledevops' || github.actor }} + IMAGE_PREFIX: ${{ (github.repository == 'specklesystems/speckle-server') && 'speckle' || 'ghcr.io/specklesystems' }} secrets: - REGISTRY_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REGISTRY_TOKEN: ${{ (github.repository == 'specklesystems/speckle-server') && secrets.DOCKERHUB_TOKEN || secrets.GITHUB_TOKEN }} deploy: - needs: [get-version, tests, builds, test-deployments, get-chart-name] + needs: [get-version, tests, builds, builds-ghcr, test-deployments, get-chart-name] uses: ./.github/workflows/publish.yml with: - IMAGE_PREFIX: 'ghcr.io/specklesystems' + IMAGE_PREFIX: ${{ (github.repository == 'specklesystems/speckle-server') && 'speckle' || 'ghcr.io/specklesystems' }} IMAGE_VERSION_TAG: ${{ needs.get-version.outputs.IMAGE_VERSION_TAG }} CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }} - OCI_REGISTRY_DOMAIN: ghcr.io - OCI_REGISTRY_PATH: specklesystems - OCI_REGISTRY_USERNAME: ${{ github.actor }} + OCI_REGISTRY_DOMAIN: ${{ (github.repository == 'specklesystems/speckle-server') && 'docker.io' || 'ghcr.io' }} + OCI_REGISTRY_PATH: ${{ (github.repository == 'specklesystems/speckle-server') && 'speckle' || 'specklesystems' }} + OCI_REGISTRY_USERNAME: ${{ (github.repository == 'specklesystems/speckle-server') && 'speckledevops' || github.actor }} CHART_NAME: ${{ needs.get-chart-name.outputs.CHART_NAME }} secrets: - # we do not inherit here as we wish to configure secrets depending on the target registry DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} - OCI_REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} # we are pushing helm chart to ghcr + OCI_REGISTRY_PASSWORD: ${{ (github.repository == 'specklesystems/speckle-server') && secrets.DOCKERHUB_TOKEN || secrets.GITHUB_TOKEN }} GH_DEVOPS_PAT: ${{ secrets.GH_DEVOPS_PAT }} + #HACK temporary job to publish helm charts to ghcr.io until we migrate everything + ghcr-helm-chart-oci: + needs: [get-version, tests, builds, builds-ghcr, test-deployments, get-chart-name] + runs-on: blacksmith-4vcpu-ubuntu-2404 + name: Helm chart oci + container: + image: speckle/pre-commit-runner:latest + env: + IMAGE_PREFIX: 'ghcr.io/specklesystems' + IMAGE_VERSION_TAG: ${{ needs.get-version.outputs.IMAGE_VERSION_TAG }} + HELM_REGISTRY_DOMAIN: 'ghcr.io' + HELM_REPOSITORY_PATH: 'specklesystems' + REGISTRY_USERNAME: ${{ github.actor }} + REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + CHART_NAME: ${{ needs.get-chart-name.outputs.CHART_NAME }} + steps: + - uses: actions/checkout@v4.2.2 + with: + fetch-depth: 0 + - run: git config --global --add safe.directory $PWD + - name: Publish Helm Chart + run: ./.github/workflows/scripts/publish_helm_chart_oci.sh + npm: needs: [get-version, tests, builds, builds-ghcr] uses: ./.github/workflows/npm.yml - # only run if a tag triggered the workflow + # only run if a tag triggered the workflow on specklesystems/speckle-server repository if: startsWith(github.ref, 'refs/tags/') with: + GITHUB_REGISTRY_URL: ${{ format('%s%s.git', 'https://github.com/', github.repository) }} + GITHUB_ORG: ${{ github.repository_owner }} + NPM_REGISTRY_URL: ${{ github.repository == 'specklesystems/speckle-server' && 'https://registry.npmjs.org/' || 'https://npm.pkg.github.com/' }} + NPM_PUBLISH_ACCESS: ${{ github.repository == 'specklesystems/speckle-server' && 'public' || 'restricted' }} IMAGE_VERSION_TAG: ${{ needs.get-version.outputs.IMAGE_VERSION_TAG }} - secrets: inherit + secrets: + NPM_TOKEN: ${{ github.repository == 'specklesystems/speckle-server' && secrets.NPM_TOKEN || github.token}} snyk: needs: [tests] diff --git a/packages/server/package.json b/packages/server/package.json index bbad33546..f0da290d8 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -3,13 +3,13 @@ "version": "2.5.4", "private": true, "description": "", - "homepage": "https://github.com/specklesystems/server", + "homepage": "https://github.com/specklesystems/speckle-server", "author": "AEC Systems", "license": "SEE LICENSE IN readme.md", "main": "./bin/www", "repository": { "type": "git", - "url": "https://github.com/specklesystems/Server.git" + "url": "https://github.com/specklesystems/speckle-server.git" }, "type": "module", "engines": {