-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a3f4417
commit 0d0bd5a
Showing
9 changed files
with
502 additions
and
35 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,11 @@ on: | |
type: boolean | ||
default: true | ||
|
||
# Run workflow upon completion of `publish` workflow run: | ||
workflow_run: | ||
workflows: ["publish"] | ||
types: [completed] | ||
|
||
# Concurrency group to prevent multiple concurrent executions: | ||
concurrency: | ||
group: productionize | ||
|
@@ -697,6 +702,192 @@ jobs: | |
channel: '#npm-ci' | ||
if: failure() | ||
|
||
# Define job to create CLI branch: | ||
cli: | ||
|
||
# Define display name: | ||
name: 'Create CLI branch' | ||
|
||
# Define the type of virtual host machine on which to run the job: | ||
runs-on: ubuntu-latest | ||
|
||
# Indicate that this job depends on the test job finishing: | ||
needs: test | ||
|
||
# Define the sequence of job steps... | ||
steps: | ||
# Checkout the repository: | ||
- name: 'Checkout repository' | ||
uses: actions/checkout@v3 | ||
|
||
# Configure git: | ||
- name: 'Configure git' | ||
run: | | ||
git config --local user.email "[email protected]" | ||
git config --local user.name "stdlib-bot" | ||
# Check if remote `cli` branch exists: | ||
- name: 'Check if remote `cli` branch exists' | ||
id: cli-branch-exists | ||
continue-on-error: true | ||
run: | | ||
git fetch --all | ||
git ls-remote --exit-code --heads origin cli | ||
if [ $? -eq 0 ]; then | ||
echo "remote-exists=true" >> $GITHUB_OUTPUT | ||
else | ||
echo "remote-exists=false" >> $GITHUB_OUTPUT | ||
fi | ||
# If `cli` exists, delete everything in branch and merge `production` into it | ||
- name: 'If `cli` exists, delete everything in branch and merge `production` into it' | ||
if: steps.cli-branch-exists.outputs.remote-exists | ||
run: | | ||
git checkout -b cli origin/cli | ||
find . -type 'f' | grep -v -e ".git/" -e "package.json" -e "README.md" -e "LICENSE" -e "CONTRIBUTORS" -e "NOTICE" | xargs -r rm | ||
find . -mindepth 1 -type 'd' | grep -v -e ".git" | xargs -r rm -rf | ||
git add -A | ||
git commit -m "Remove files" --allow-empty | ||
git config merge.theirs.name 'simulate `-s theirs`' | ||
git config merge.theirs.driver 'cat %B > %A' | ||
GIT_CONFIG_PARAMETERS="'merge.default=theirs'" git merge origin/production --allow-unrelated-histories | ||
# Copy files from `production` branch if necessary: | ||
git checkout origin/production -- . | ||
if [ -n "$(git status --porcelain)" ]; then | ||
git add -A | ||
git commit -m "Auto-generated commit" | ||
fi | ||
# If `cli` does not exist, create `cli` branch: | ||
- name: 'If `cli` does not exist, create `cli` branch' | ||
if: ${{ steps.cli-branch-exists.outputs.remote-exists == false }} | ||
run: | | ||
git checkout production | ||
git checkout -b cli | ||
# Copy files to cli directory: | ||
- name: 'Copy files to cli directory' | ||
run: | | ||
mkdir -p cli | ||
mkdir -p cli/docs cli/test | ||
cp README.md LICENSE CONTRIBUTORS NOTICE ./cli | ||
cp -r bin etc ./cli | ||
cp -r test/test.cli.js test/fixtures ./cli/test | ||
cp docs/usage.txt ./cli/docs | ||
# Install Node.js: | ||
- name: 'Install Node.js' | ||
uses: actions/setup-node@v3 | ||
with: | ||
node-version: 16 | ||
timeout-minutes: 5 | ||
|
||
# Install dependencies: | ||
- name: 'Install production and development dependencies' | ||
id: install | ||
run: | | ||
npm install || npm install || npm install | ||
timeout-minutes: 15 | ||
|
||
# Rewrite file contents: | ||
- name: 'Rewrite file contents' | ||
run: | | ||
# Define variable for package name: | ||
pkg="$(jq -r '.name' ./package.json)" | ||
pkgDescription="$(jq -r '.description' ./package.json)" | ||
escapedPkg=$(echo "$pkg" | sed -e 's/\//\\\//g') | ||
escapedPkg=$(echo "$escapedPkg" | sed -e 's/\@/\\\@/g') | ||
# Remove sections: | ||
find ./cli -type f -name '*.md' -print0 | xargs -0 perl -0777 -i -pe "s/<section class=\"installation\">[^<]+<\/section>//;" | ||
find ./cli -type f -name '*.md' -print0 | xargs -0 perl -0777 -i -pe "s/(\* \* \*\n+)?<section class=\"usage\">[\s\S]+?<\!\-\- \/.usage \-\->//" | ||
find ./cli -type f -name '*.md' -print0 | xargs -0 perl -0777 -i -pe "s/(\* \* \*\n+)?<section class=\"notes\">[\s\S]+?<\!\-\- \/.notes \-\->//" | ||
find ./cli -type f -name '*.md' -print0 | xargs -0 perl -0777 -i -pe "s/(\* \* \*\n+)?<section class=\"examples\">[\s\S]+?<\!\-\- \/.examples \-\->//" | ||
find ./cli -type f -name '*.md' -print0 | xargs -0 perl -0777 -i -pe "s/(\* \* \*\n+)?<section class=\"c\">[\s\S]+?<\!\-\- \/.c \-\->//g" | ||
# Remove first horizontal rule * * *: | ||
find ./cli -type f -name '*.md' -print0 | xargs -0 perl -0777 -i -pe "s/(\* \* \*)//" | ||
# Remove ## CLI heading: | ||
find ./cli -type f -name '*.md' -print0 | xargs -0 perl -0777 -i -pe "s/## CLI//" | ||
# Change heading levels: | ||
find ./cli -type f -name '*.md' -print0 | xargs -0 perl -0777 -i -pe "s/###/##/g" | ||
# Append -cli to package name unless it already ends with -cli: | ||
find ./cli -type f -name '*.md' -print0 | xargs -0 perl -0777 -i -pe "s/($escapedPkg)(?!-cli)/\1-cli/g" | ||
# Insert a link to the main package: | ||
find ./cli -type f -name '*.md' -print0 | xargs -0 perl -0777 -i -pe "s/<section class=\"related\">(?:\n\n\* \* \*\n\n## See Also\n\n)?/<section class=\"related\">\n\n## See Also\n\n- <span class=\"package-name\">[\`$escapedPkg\`][main-url]<\/span><span class=\"delimiter\">: <\/span><span class=\"description\">$pkgDescription<\/span>\n/" | ||
# Create package.json file for cli branch: | ||
jq --indent 2 '.name = .name + "-cli" | {"name": .name, "version": .version, "description": .description, "license": .license, "author": .author, "contributors": .contributors, "bin": .bin, "homepage": .homepage, "repository": .repository, "bugs": .bugs, "dependencies": .dependencies, "devDependencies": .devDependencies, "keywords": .keywords, "funding": .funding}' package.json > ./cli/package.json | ||
# Add implementation package as dependency: | ||
version=$(npm view "$pkg" version) | ||
jq --indent 2 ".dependencies[\"$pkg\"] = \"$version\"" ./cli/package.json > ./cli/package.json.tmp | ||
mv ./cli/package.json.tmp ./cli/package.json | ||
# Rewrite require of main module in bin/cli to depend on external package: | ||
perl -0777 -i -pe "s/require\( \'\.\/\.\.\/lib\' \)/require\( \'$escapedPkg\' \)/" ./cli/bin/cli | ||
# For all dependencies, check if they are required by the CLI (test/test.cli.js and bin/cli); if not, remove them: | ||
jq -r '.dependencies | keys[]' ./cli/package.json | while read -r dep; do | ||
dep=$(echo "$dep" | xargs) | ||
if ! grep -q "$dep" ./cli/test/test.cli.js && ! grep -q "$dep" ./cli/bin/cli; then | ||
jq --indent 2 "del(.dependencies[\"$dep\"])" ./cli/package.json > ./cli/package.json.tmp | ||
mv ./cli/package.json.tmp ./cli/package.json | ||
fi | ||
done | ||
jq -r '.devDependencies | keys[]' ./cli/package.json | while read -r dep; do | ||
if [[ "$dep" != "@stdlib"* ]]; then | ||
continue | ||
fi | ||
dep=$(echo "$dep" | xargs) | ||
if ! grep -q "$dep" ./cli/test/test.cli.js && ! grep -q "$dep" ./cli/bin/cli; then | ||
jq --indent 2 "del(.devDependencies[\"$dep\"])" ./cli/package.json > ./cli/package.json.tmp | ||
mv ./cli/package.json.tmp ./cli/package.json | ||
fi | ||
done | ||
# Delete everything in current directory aside from cli folder: | ||
- name: 'Delete everything in current directory aside from cli folder' | ||
run: | | ||
find . -type 'f' | grep -v -e "cli" -e ".git/" | xargs -r rm | ||
find . -mindepth 1 -type 'd' | grep -v -e "cli" -e ".git" | xargs -r rm -rf | ||
# Move cli directory to root: | ||
- name: 'Move cli directory to root' | ||
run: | | ||
mv ./cli/* . | ||
rmdir ./cli | ||
# Commit changes: | ||
- name: 'Commit changes' | ||
run: | | ||
git add -A | ||
git commit -m "Auto-generated commit" | ||
# Push changes to `cli` branch: | ||
- name: 'Push changes to `cli` branch' | ||
run: | | ||
SLUG=${{ github.repository }} | ||
echo "Pushing changes to $SLUG..." | ||
git push "https://$GITHUB_ACTOR:[email protected]/$SLUG.git" cli | ||
# Send status to Slack channel if job fails: | ||
- name: 'Send status to Slack channel in case of failure' | ||
uses: act10ns/slack@v1 | ||
with: | ||
status: ${{ job.status }} | ||
steps: ${{ toJson(steps) }} | ||
channel: '#npm-ci' | ||
if: failure() | ||
|
||
# Define job that succeeds if all bundles were successfully built: | ||
create-tag-bundles: | ||
|
||
|
@@ -707,7 +898,7 @@ jobs: | |
runs-on: ubuntu-latest | ||
|
||
# Indicate that this job depends on the bundle jobs finishing: | ||
needs: [ deno, umd, esm ] | ||
needs: [ deno, umd, esm, cli ] | ||
|
||
# Define the steps to be executed: | ||
steps: | ||
|
@@ -789,3 +980,15 @@ jobs: | |
git add README.md | ||
git commit -m "Auto-generated commit" | ||
git push "https://$GITHUB_ACTOR:[email protected]/$SLUG.git" esm | ||
git checkout -b cli origin/cli | ||
sed -i -E "s/$ESCAPED/$ESCAPED@$VERSION/g" README.md | ||
git add README.md | ||
git commit -m "Update README.md for CLI branch $VERSION" | ||
git tag -a $VERSION-cli -m "$VERSION-cli" | ||
git push "https://$GITHUB_ACTOR:[email protected]/$SLUG.git" $VERSION-cli | ||
sed -i -E "s/$ESCAPED@$VERSION/$ESCAPED/g" README.md | ||
git add README.md | ||
git commit -m "Auto-generated commit" | ||
git push "https://$GITHUB_ACTOR:[email protected]/$SLUG.git" cli |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,9 +21,23 @@ name: publish | |
|
||
# Workflow triggers: | ||
on: | ||
# Run workflow when a new tag is pushed to the repository: | ||
push: | ||
tags: v[0-9]+.[0-9]+.[0-9]+ | ||
# Allow the workflow to be manually run: | ||
workflow_dispatch: | ||
# Workflow inputs: | ||
inputs: | ||
version: | ||
description: 'Version Increment' | ||
type: choice | ||
default: 'none' | ||
options: | ||
- 'none' | ||
- 'major' | ||
- 'minor' | ||
- 'patch' | ||
- 'premajor' | ||
- 'preminor' | ||
- 'prepatch' | ||
- 'prerelease' | ||
|
||
# Workflow jobs: | ||
jobs: | ||
|
@@ -32,14 +46,15 @@ jobs: | |
publish: | ||
|
||
# Define display name: | ||
name: 'Publish to npm' | ||
name: 'Publish package to npm' | ||
|
||
# Define the type of virtual host machine on which to run the job: | ||
runs-on: ubuntu-latest | ||
|
||
# Define environment variables: | ||
env: | ||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} | ||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
|
||
# Define the sequence of job steps... | ||
steps: | ||
|
@@ -55,6 +70,72 @@ jobs: | |
node-version: 16 | ||
timeout-minutes: 5 | ||
|
||
# Configure git: | ||
- name: 'Configure git' | ||
run: | | ||
git config --local user.email "[email protected]" | ||
git config --local user.name "stdlib-bot" | ||
# Increment package version (if requested): | ||
- name: 'Increment package version (if requested)' | ||
if: ${{ github.event.inputs.version != 'none' }} | ||
run: | | ||
# Save NPM_TOKEN to user's .npmrc: | ||
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc | ||
# Increment package version: | ||
npm version ${{ github.event.inputs.version }} --no-git-tag-version | ||
# Define variable for new version: | ||
NEW_VERSION=$(node -p "require('./package.json').version") | ||
# Replace branch in README.md link definitions for badges with the new version: | ||
find . -type f -name '*.md' -print0 | xargs -0 sed -Ei "s/branch([=:])[^ ]+/branch\1v${NEW_VERSION}/g" | ||
# Create a new commit and tag: | ||
git add package.json README.md | ||
git commit -m "Release v${NEW_VERSION}" | ||
git tag -a "v${NEW_VERSION}" -m "Release v${NEW_VERSION}" | ||
# Push changes to GitHub: | ||
SLUG=${{ github.repository }} | ||
git push "https://$GITHUB_ACTOR:[email protected]/$SLUG.git" --follow-tags | ||
# Remove CLI: | ||
- name: 'Remove CLI' | ||
if: ${{ github.ref == 'refs/heads/main' }} | ||
run: | | ||
rm -rf ./bin/cli | ||
rm test/test.cli.js | ||
rm etc/cli_opts.json | ||
rm docs/usage.txt | ||
# For all dependencies, check in all *.js files if they are still used; if not, remove them: | ||
jq -r '.dependencies | keys[]' ./package.json | while read -r dep; do | ||
dep=$(echo "$dep" | xargs) | ||
if ! grep -q "$dep" lib/**; then | ||
jq --indent 2 "del(.dependencies[\"$dep\"])" ./package.json > ./package.json.tmp | ||
mv ./package.json.tmp ./package.json | ||
fi | ||
done | ||
jq -r '.devDependencies | keys[]' ./package.json | while read -r dep; do | ||
if [[ "$dep" != "@stdlib"* ]]; then | ||
continue | ||
fi | ||
dep=$(echo "$dep" | xargs) | ||
if ! grep -q "$dep" ./lib/**; then | ||
jq --indent 2 "del(.devDependencies[\"$dep\"])" ./package.json > ./package.json.tmp | ||
mv ./package.json.tmp ./package.json | ||
fi | ||
done | ||
# Remove CLI section: | ||
find . -type f -name '*.md' -print0 | xargs -0 perl -0777 -i -pe "s/(\* \* \*\n+)?<section class=\"cli\">[\s\S]+?<\!\-\- \/.cli \-\->//" | ||
# Remove CLI from package.json: | ||
jq -r 'del(.bin)' package.json > package.json.tmp | ||
mv package.json.tmp package.json | ||
# Replace GitHub links to individual packages with npm links: | ||
- name: 'Replace all GitHub links to individual packages with npm links' | ||
run: | | ||
|
@@ -68,7 +149,26 @@ jobs: | |
# Replace all stdlib GitHub dependencies with the respective npm packages: | ||
- name: 'Replace all stdlib GitHub dependencies with the respective npm packages' | ||
run: | | ||
find package.json -type f -print0 | xargs -0 sed -Ei 's/"github:stdlib-js[^"]*"/"^0.0.x"/g' | ||
for dep in $(jq -r '.dependencies | keys | .[]' package.json); do | ||
if [[ "$dep" != "@stdlib"* ]]; then | ||
continue | ||
fi | ||
# Trim leading and trailing whitespace: | ||
dep=$(echo "$dep" | xargs) | ||
version="^$(npm view $dep version)" | ||
jq -r --arg dep "$dep" --arg version "$version" '.dependencies[$dep] = $version' package.json > package.json.tmp | ||
mv package.json.tmp package.json | ||
done | ||
for dep in $(jq -r '.devDependencies | keys | .[]' package.json); do | ||
if [[ "$dep" != "@stdlib"* ]]; then | ||
continue | ||
fi | ||
# Trim leading and trailing whitespace: | ||
dep=$(echo "$dep" | xargs) | ||
version="^$(npm view $dep version)" | ||
jq -r --arg dep "$dep" --arg version "$version" '.devDependencies[$dep] = $version' package.json > package.json.tmp | ||
mv package.json.tmp package.json | ||
done | ||
# Publish package to npm: | ||
- name: 'Publish package to npm' | ||
|
Oops, something went wrong.