Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .czrc

This file was deleted.

45 changes: 45 additions & 0 deletions .github/workflows/commitlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Commitlint

permissions:
contents: read

on:
pull_request:
types: [opened, edited, reopened, synchronize, ready_for_review]
push:
branches:
- main

jobs:
commitlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0

- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
package-manager-cache: false

- uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3

- run: pnpm install --prefer-offline --frozen-lockfile

- name: Lint pull request title
if: github.event_name == 'pull_request'
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: printf '%s\n' "$PR_TITLE" | pnpm exec commitlint

- name: Lint pushed commits
if: github.event_name == 'push'
env:
COMMITLINT_FROM: ${{ github.event.before }}
run: |
if [[ "$COMMITLINT_FROM" =~ ^0+$ ]]; then
exit 0
fi
pnpm exec commitlint --from "$COMMITLINT_FROM" --to "$GITHUB_SHA" --verbose
2 changes: 1 addition & 1 deletion .github/workflows/main-pipeline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
# - Markdown plus docs/documentation changes do not trigger build, unit, native, or E2E jobs.
# - Implementation E2E jobs run only for implementations relevant to changed paths.
# - Skipped E2E jobs due to unmatched filters are expected behavior.
# - Keep this mapping aligned with CONTRIBUTING.md ("E2E Coverage and Environment").
# - Keep this mapping aligned with CONTRIBUTING.md ("E2E jobs").
filters: |
build:
- '{lib/**,packages/**,implementations/**,package.json,pnpm-lock.yaml,pnpm-workspace.yaml,tsconfig*.json,.github/workflows/main-pipeline.yaml}'
Expand Down
16 changes: 13 additions & 3 deletions .github/workflows/publish-android.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
workflow_dispatch:
inputs:
tag:
description: 'Existing release tag (e.g. v1.2.3)'
description: 'Existing Android release tag (e.g. optimization-android-v1.2.3)'
required: true
publish:
description: 'Actually publish'
Expand All @@ -18,6 +18,9 @@ on:

jobs:
publish:
if:
github.event_name == 'workflow_dispatch' || startsWith(github.event.release.tag_name,
'optimization-android-v')
runs-on: ubuntu-latest
steps:
- name: Derive release version
Expand All @@ -27,8 +30,15 @@ jobs:
else
TAG='${{ inputs.tag }}'
fi
echo "RELEASE_TAG=$TAG" >> "$GITHUB_ENV"
echo "RELEASE_VERSION=${TAG#v}" >> "$GITHUB_ENV"
case "$TAG" in
optimization-android-v*) ;;
*)
echo "Expected optimization-android-v* tag, got $TAG." >&2
exit 1
;;
esac
echo "RELEASE_TAG=$TAG" >> "$GITHUB_ENV"
echo "RELEASE_VERSION=${TAG#optimization-android-v}" >> "$GITHUB_ENV"

- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
Expand Down
154 changes: 120 additions & 34 deletions .github/workflows/publish-npm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ permissions:
id-token: write
packages: write

concurrency:
group: publish-npm-${{ github.event.release.target_commitish || inputs.tag || github.run_id }}
cancel-in-progress: false

on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Existing release tag (e.g. v1.2.3)'
description: 'Existing package release tag (e.g. optimization-core-v1.2.3)'
required: true
publish:
description: 'Actually publish'
Expand All @@ -22,31 +26,21 @@ jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Retrieve Secrets from Vault
if: github.event_name == 'release' || inputs.publish
id: vault
uses: hashicorp/vault-action@4c06c5ccf5c0761b6029f56cfb1dcf5565918a3b # v3.4.0
with:
url: ${{ secrets.VAULT_URL }}
role: ${{ github.event.repository.name }}-github-action
method: jwt
path: github-actions
secrets: |
secret/data/github/github_packages_write GITHUB_PACKAGES_WRITE_TOKEN | GITHUB_PACKAGES_WRITE_TOKEN;

- name: Derive release version
- name: Derive release tag
id: release_tag
run: |
if [ "${{ github.event_name }}" = "release" ]; then
TAG='${{ github.event.release.tag_name }}'
else
TAG='${{ inputs.tag }}'
fi
echo "RELEASE_TAG=$TAG" >> "$GITHUB_ENV"
echo "RELEASE_VERSION=${TAG#v}" >> "$GITHUB_ENV"
echo "release_tag=$TAG" >> "$GITHUB_OUTPUT"

- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.tag }}
ref: ${{ steps.release_tag.outputs.release_tag }}
fetch-depth: 0

- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
Expand All @@ -61,32 +55,86 @@ jobs:
- name: Resolve npm package targets
id: npm_package_targets
run: |
echo "pnpm_filters=$(./node_modules/.bin/tsx scripts/list-npm-package-targets.ts npm-pnpm-filters)" >> "$GITHUB_OUTPUT"
if [ "${{ github.event_name }}" = "release" ]; then
mapfile -t release_tags < <(git tag --points-at HEAD 'optimization-*-v*' | sort)
else
release_tags=("$RELEASE_TAG")
fi

- name: Bump package.json versions
run: |
pnpm -r ${{ steps.npm_package_targets.outputs.pnpm_filters }} exec \
npm --no-git-tag-version --force version "$RELEASE_VERSION"
env:
RELEASE_VERSION: ${{ env.RELEASE_VERSION }}
release_targets="$(./node_modules/.bin/tsx scripts/list-npm-package-targets.ts released-npm-targets "${release_tags[@]}")"
pnpm_filters="$(./node_modules/.bin/tsx scripts/list-npm-package-targets.ts released-npm-pnpm-filters "${release_tags[@]}")"

if [ -z "$release_targets" ]; then
echo "has_targets=false" >> "$GITHUB_OUTPUT"
exit 0
fi

IFS=$'\t' read -r package_name _package_dir _report_path _release_tag release_version <<< "$(printf '%s\n' "$release_targets" | head -n 1)"

if [ -z "$package_name" ] || [ -z "$release_version" ]; then
echo "Invalid npm release target: $release_targets" >&2
exit 1
fi

{
echo "has_targets=true"
echo "release_tags<<EOF"
printf '%s\n' "${release_tags[@]}"
echo "EOF"
echo "release_targets<<EOF"
printf '%s\n' "$release_targets"
echo "EOF"
echo "pnpm_filters=$pnpm_filters"
} >> "$GITHUB_OUTPUT"

- name: Retrieve Secrets from Vault
if:
steps.npm_package_targets.outputs.has_targets == 'true' && (github.event_name == 'release'
|| inputs.publish)
id: vault
uses: hashicorp/vault-action@4c06c5ccf5c0761b6029f56cfb1dcf5565918a3b # v3.4.0
with:
url: ${{ secrets.VAULT_URL }}
role: ${{ github.event.repository.name }}-github-action
method: jwt
path: github-actions
secrets: |
secret/data/github/github_packages_write GITHUB_PACKAGES_WRITE_TOKEN | GITHUB_PACKAGES_WRITE_TOKEN;

- name: Build
if: steps.npm_package_targets.outputs.has_targets == 'true'
run: pnpm build
env:
RELEASE_VERSION: ${{ env.RELEASE_VERSION }}

- name: Generate npm third-party notices
if: steps.npm_package_targets.outputs.has_targets == 'true'
run: pnpm notices:generate:npm

- name: Prepare package READMEs for publish
run: |
pnpm -r ${{ steps.npm_package_targets.outputs.pnpm_filters }} exec build-tools rewrite-readme prepare
if: steps.npm_package_targets.outputs.has_targets == 'true'
env:
RELEASE_TAG: ${{ env.RELEASE_TAG }}
RELEASE_TARGETS: ${{ steps.npm_package_targets.outputs.release_targets }}
run: |
while IFS= read -r target_info; do
if [ -z "$target_info" ]; then
continue
fi

IFS=$'\t' read -r _package_name package_dir _report_path release_tag _release_version <<< "$target_info"

if [ -z "$package_dir" ] || [ -z "$release_tag" ]; then
echo "Invalid npm README target: $target_info" >&2
exit 1
fi

RELEASE_TAG="$release_tag" pnpm --dir "$package_dir" exec build-tools rewrite-readme prepare
done <<< "$RELEASE_TARGETS"

- name: Stage third-party notices for publish
if: steps.npm_package_targets.outputs.has_targets == 'true'
env:
NOTICE_TARGETS: ${{ steps.npm_package_targets.outputs.release_targets }}
run: |
notice_targets="$(./node_modules/.bin/tsx scripts/list-npm-package-targets.ts npm-targets)"
notice_targets="$NOTICE_TARGETS"

if [ -z "$notice_targets" ]; then
echo "No npm notice targets found." >&2
Expand All @@ -98,7 +146,7 @@ jobs:
continue
fi

IFS=$'\t' read -r package_name package_dir report_path <<< "$target_info"
IFS=$'\t' read -r package_name package_dir report_path _release_tag _release_version <<< "$target_info"

if [ -z "$package_name" ] || [ -z "$package_dir" ] || [ -z "$report_path" ]; then
echo "Invalid npm notice target: $target_info" >&2
Expand All @@ -119,12 +167,18 @@ jobs:
done <<< "$notice_targets"

- name: Create packages for troubleshooting
run: pnpm run pack:pkgs
if: steps.npm_package_targets.outputs.has_targets == 'true'
run: |
rm -rf pkgs
mkdir -p pkgs
pnpm pack ${{ steps.npm_package_targets.outputs.pnpm_filters }} --pack-destination pkgs

- name: Verify packages include third-party notices
if: steps.npm_package_targets.outputs.has_targets == 'true'
run: bash ./scripts/verify-npm-package-notices.sh pkgs

- name: Upload packages for troubleshooting
if: steps.npm_package_targets.outputs.has_targets == 'true'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ci-optimization-sdk-packages
Expand All @@ -133,16 +187,48 @@ jobs:
retention-days: 3

- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
if: github.event_name == 'release' || inputs.publish
if:
steps.npm_package_targets.outputs.has_targets == 'true' && (github.event_name == 'release'
|| inputs.publish)
with:
node-version-file: '.nvmrc'
registry-url: 'https://npm.pkg.github.com'
scope: '@contentful'
package-manager-cache: false

- name: Resolve unpublished targets
if:
steps.npm_package_targets.outputs.has_targets == 'true' && (github.event_name == 'release'
|| inputs.publish)
id: unpublished_targets
env:
NODE_AUTH_TOKEN: ${{ steps.vault.outputs.GITHUB_PACKAGES_WRITE_TOKEN }}
RELEASE_TARGETS: ${{ steps.npm_package_targets.outputs.release_targets }}
run: |
publish_filters=()

while IFS= read -r target_info; do
if [ -z "$target_info" ]; then
continue
fi

IFS=$'\t' read -r package_name _package_dir _report_path _release_tag release_version <<< "$target_info"

if npm view "$package_name@$release_version" version --registry=https://npm.pkg.github.com >/dev/null 2>&1; then
echo "$package_name@$release_version is already published; skipping."
continue
fi

publish_filters+=(--filter "$package_name")
done <<< "$RELEASE_TARGETS"

echo "pnpm_filters=${publish_filters[*]}" >> "$GITHUB_OUTPUT"

- name: Publish
if: github.event_name == 'release' || inputs.publish
if:
steps.unpublished_targets.outputs.pnpm_filters != '' && (github.event_name == 'release' ||
inputs.publish)
run: |
pnpm -r ${{ steps.npm_package_targets.outputs.pnpm_filters }} publish --access public --no-git-checks
pnpm -r ${{ steps.unpublished_targets.outputs.pnpm_filters }} publish --access public --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ steps.vault.outputs.GITHUB_PACKAGES_WRITE_TOKEN }}
24 changes: 18 additions & 6 deletions .github/workflows/publish-spm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
workflow_dispatch:
inputs:
tag:
description: 'Existing release tag (e.g. v1.2.3)'
description: 'Existing Swift release tag (e.g. optimization-swift-v1.2.3)'
required: true
publish:
description: 'Actually publish'
Expand All @@ -18,6 +18,9 @@ on:

jobs:
publish:
if:
github.event_name == 'workflow_dispatch' || startsWith(github.event.release.tag_name,
'optimization-swift-v')
runs-on: macos-latest
steps:
- name: Derive release version
Expand All @@ -27,8 +30,17 @@ jobs:
else
TAG='${{ inputs.tag }}'
fi
echo "RELEASE_TAG=$TAG" >> "$GITHUB_ENV"
echo "RELEASE_VERSION=${TAG#v}" >> "$GITHUB_ENV"
case "$TAG" in
optimization-swift-v*) ;;
*)
echo "Expected optimization-swift-v* tag, got $TAG." >&2
exit 1
;;
esac
VERSION="${TAG#optimization-swift-v}"
echo "RELEASE_TAG=$TAG" >> "$GITHUB_ENV"
echo "RELEASE_VERSION=$VERSION" >> "$GITHUB_ENV"
echo "SPM_RELEASE_TAG=v$VERSION" >> "$GITHUB_ENV"

- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
Expand Down Expand Up @@ -94,8 +106,8 @@ jobs:
echo "No content changes since the last release commit; moving the tag only."
else
git -c user.name='contentful-ci' -c user.email='ci@contentful.com' \
commit -m "Release $RELEASE_TAG (from contentful/optimization@${GITHUB_SHA:0:7})"
commit -m "Release $SPM_RELEASE_TAG (from contentful/optimization@${GITHUB_SHA:0:7})"
git push origin HEAD:main
fi
git tag --force "$RELEASE_TAG"
git push origin "refs/tags/$RELEASE_TAG" --force
git tag --force "$SPM_RELEASE_TAG"
git push origin "refs/tags/$SPM_RELEASE_TAG" --force
Loading
Loading