Skip to content

PyPI & npm Repositories

Nexus hosts both Python (PyPI) and Node.js (npm) package repositories, combining CWIQ-published packages with proxied upstream registries behind a single authenticated endpoint.


PyPI (Python Packages)

Repository URLs

Operation URL
Publish (twine) https://nexus.shared.cwiq.io/repository/pypi-hosted/
Install (pip) https://nexus.shared.cwiq.io/repository/pypi-group/simple/

The pypi-group repository combines:

  • pypi-hosted — CWIQ-published packages (e.g., cwiq-common)
  • A PyPI.org proxy cache — all public packages

Pipelines always install from pypi-group. This means pip install cwiq-common and pip install fastapi both resolve through the same Nexus URL, with no direct internet access required.

Primary Package: cwiq-common

cwiq-common is the shared Python library published by the cwiq-common project and consumed by every platform microservice. It provides shared auth helpers, base models, event definitions, and the HTTP client used for inter-service communication.

Current published version: 0.2.0

Installing from Nexus PyPI

# Install a single package
pip install \
  --index-url https://nexus.shared.cwiq.io/repository/pypi-group/simple/ \
  --trusted-host nexus.shared.cwiq.io \
  cwiq-common==0.2.0

# Install all project dependencies (with pip.conf or requirements.txt index)
pip install \
  --index-url https://nexus.shared.cwiq.io/repository/pypi-group/simple/ \
  --trusted-host nexus.shared.cwiq.io \
  -r requirements.txt

Installing in a Dockerfile

# Install from Nexus PyPI inside the container build
RUN pip install \
    --index-url https://nexus.shared.cwiq.io/repository/pypi-group/simple/ \
    --trusted-host nexus.shared.cwiq.io \
    --no-cache-dir \
    cwiq-common==0.2.0

Authentication in CI/CD

CI/CD pipelines authenticate to Nexus PyPI using credentials fetched from Vault (path: secret/nexus/svc-orchestrator). The shared Python CI template handles this automatically. For local development, your Authentik SSO credentials work for the Nexus Web UI, but pip requires a separate basic-auth credential from your Nexus account settings.

Publishing a Python Package

# Build the wheel
python -m build

# Publish to Nexus PyPI hosted repo
twine upload \
  --repository-url https://nexus.shared.cwiq.io/repository/pypi-hosted/ \
  --username "${NEXUS_USER}" \
  --password "${NEXUS_PASSWORD}" \
  dist/*

In CI/CD, this is handled by the .publish-pypi template from .gitlab-ci-python.yml. Individual projects extend it:

publish-pypi:
  extends: .publish-pypi
  rules:
    - if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+/'

Versioning Python packages

The version is sourced from pyproject.toml. Use the feat:, fix:, and feat!: conventional commit prefixes to signal the appropriate semver bump. The release-manager agent handles the version bump and CHANGELOG update.


npm (Node.js Packages)

Repository URLs

npm uses nexus.dev.cwiq.io

npm repositories are hosted on the Dev Nexus instance (nexus.dev.cwiq.io), not the Shared instance. This is the only artifact type that differs.

Operation URL
Publish https://nexus.dev.cwiq.io/repository/npm-hosted/
Install https://nexus.dev.cwiq.io/repository/npm-group/

The npm-group repository combines:

  • npm-hosted — CWIQ-published npm packages
  • An npmjs.org proxy cache — all public packages

Configuring npm

Set the registry for your project by adding an .npmrc file:

# .npmrc — project-level
registry=https://nexus.dev.cwiq.io/repository/npm-group/

Or scope it to the @cwiq namespace:

# .npmrc — scoped to @cwiq packages only
@cwiq:registry=https://nexus.dev.cwiq.io/repository/npm-hosted/

Installing Packages

# Install all dependencies using .npmrc registry configuration
npm install

# Install a specific package
npm install --registry https://nexus.dev.cwiq.io/repository/npm-group/ some-package

GitLab Package Registry (Current UI Practice)

The ui project currently also publishes to GitLab's built-in npm registry for internal scoped packages. This is set up per-project rather than through Nexus:

# .npmrc for GitLab Package Registry (project-scoped)
@cwiq:registry=${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/npm/
//${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}

This pattern works without additional Vault auth because CI_JOB_TOKEN is automatically available in every CI/CD job.