# Build, publish npm packages, and push Docker images # Runs only on main branch push/tag variables: - &node_image 'node:22-alpine' - &enable_pnpm 'corepack enable' when: - branch: [main] event: [push, manual, tag] steps: install: image: *node_image commands: - corepack enable - pnpm install --frozen-lockfile build: image: *node_image commands: - *enable_pnpm - pnpm build depends_on: - install publish-npm: image: *node_image environment: NPM_TOKEN: from_secret: gitea_token commands: - *enable_pnpm # Configure auth for Gitea npm registry - | echo "//git.mosaicstack.dev/api/packages/mosaicstack/npm/:_authToken=$NPM_TOKEN" > ~/.npmrc echo "@mosaicstack:registry=https://git.mosaicstack.dev/api/packages/mosaicstack/npm/" >> ~/.npmrc # Publish non-private packages to Gitea. # # The only publish failure we tolerate is "version already exists" — # that legitimately happens when only some packages were bumped in # the merge. Any other failure (registry 404, auth error, network # error) MUST fail the pipeline loudly: the previous # `|| echo "... continuing"` fallback silently hid a 404 from the # Gitea org rename and caused every @mosaicstack/* publish to fall # on the floor while CI still reported green. - | # Portable sh (Alpine ash) — avoid bashisms like PIPESTATUS. set +e pnpm --filter "@mosaicstack/*" --filter "!@mosaicstack/web" publish --no-git-checks --access public >/tmp/publish.log 2>&1 EXIT=$? set -e cat /tmp/publish.log if [ "$EXIT" -eq 0 ]; then echo "[publish] all packages published successfully" exit 0 fi # Hard registry / auth / network errors → fatal. Match npm's own # error lines specifically to avoid false positives on arbitrary # log text that happens to contain "E404" etc. if grep -qE "npm (error|ERR!) code (E404|E401|ENEEDAUTH|ECONNREFUSED|ETIMEDOUT|ENOTFOUND)" /tmp/publish.log; then echo "[publish] FATAL: registry/auth/network error detected — failing pipeline" >&2 exit 1 fi # Only tolerate the explicit "version already published" case. # npm returns this as E403 with body "You cannot publish over..." # or EPUBLISHCONFLICT depending on version. if grep -qE "EPUBLISHCONFLICT|You cannot publish over|previously published" /tmp/publish.log; then echo "[publish] some packages already at this version — continuing (non-fatal)" exit 0 fi echo "[publish] FATAL: publish failed with unrecognized error — failing pipeline" >&2 exit 1 depends_on: - build # TODO: Uncomment when ready to publish to npmjs.org # publish-npmjs: # image: *node_image # environment: # NPM_TOKEN: # from_secret: npmjs_token # commands: # - *enable_pnpm # - apk add --no-cache jq bash # - bash scripts/publish-npmjs.sh # depends_on: # - build # when: # - event: [tag] build-gateway: image: gcr.io/kaniko-project/executor:debug environment: REGISTRY_USER: from_secret: gitea_username REGISTRY_PASS: from_secret: gitea_password CI_COMMIT_BRANCH: ${CI_COMMIT_BRANCH} CI_COMMIT_TAG: ${CI_COMMIT_TAG} CI_COMMIT_SHA: ${CI_COMMIT_SHA} commands: - mkdir -p /kaniko/.docker - echo "{\"auths\":{\"git.mosaicstack.dev\":{\"username\":\"$REGISTRY_USER\",\"password\":\"$REGISTRY_PASS\"}}}" > /kaniko/.docker/config.json - | DESTINATIONS="--destination git.mosaicstack.dev/mosaicstack/stack/gateway:sha-${CI_COMMIT_SHA:0:7}" if [ "$CI_COMMIT_BRANCH" = "main" ]; then DESTINATIONS="$DESTINATIONS --destination git.mosaicstack.dev/mosaicstack/stack/gateway:latest" fi if [ -n "$CI_COMMIT_TAG" ]; then DESTINATIONS="$DESTINATIONS --destination git.mosaicstack.dev/mosaicstack/stack/gateway:$CI_COMMIT_TAG" fi /kaniko/executor --context . --dockerfile docker/gateway.Dockerfile $DESTINATIONS depends_on: - build build-web: image: gcr.io/kaniko-project/executor:debug environment: REGISTRY_USER: from_secret: gitea_username REGISTRY_PASS: from_secret: gitea_password CI_COMMIT_BRANCH: ${CI_COMMIT_BRANCH} CI_COMMIT_TAG: ${CI_COMMIT_TAG} CI_COMMIT_SHA: ${CI_COMMIT_SHA} commands: - mkdir -p /kaniko/.docker - echo "{\"auths\":{\"git.mosaicstack.dev\":{\"username\":\"$REGISTRY_USER\",\"password\":\"$REGISTRY_PASS\"}}}" > /kaniko/.docker/config.json - | DESTINATIONS="--destination git.mosaicstack.dev/mosaicstack/stack/web:sha-${CI_COMMIT_SHA:0:7}" if [ "$CI_COMMIT_BRANCH" = "main" ]; then DESTINATIONS="$DESTINATIONS --destination git.mosaicstack.dev/mosaicstack/stack/web:latest" fi if [ -n "$CI_COMMIT_TAG" ]; then DESTINATIONS="$DESTINATIONS --destination git.mosaicstack.dev/mosaicstack/stack/web:$CI_COMMIT_TAG" fi /kaniko/executor --context . --dockerfile docker/web.Dockerfile $DESTINATIONS depends_on: - build