Merge pull request #14014 from tschaub/release-job

Release actions
This commit is contained in:
Tim Schaub
2022-08-18 20:15:42 -06:00
committed by GitHub
8 changed files with 261 additions and 10 deletions

View File

@@ -1,4 +1,4 @@
name: Deploy Preview name: Deploy Website (Preview)
on: on:
workflow_run: workflow_run:

View File

@@ -1,16 +1,18 @@
name: Deploy name: Deploy Website
on: on:
push: push:
branches: branches:
- main - main
tags:
- 'v*.*.*'
concurrency: concurrency:
group: "deploy" group: "deploy"
cancel-in-progress: true
jobs: jobs:
deploy: deploy-branch:
if: startsWith(github.ref, 'refs/heads/')
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@@ -35,3 +37,31 @@ jobs:
git add . git add .
git commit -m "Website updates" git commit -m "Website updates"
git push origin main git push origin main
deploy-tag:
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Assert Latest Release
run: node tasks/newest-tag.js --tag ${GITHUB_REF_NAME}
- name: Build Website
run: ./tasks/build-website.sh -l ${GITHUB_REF_NAME} -v ${GITHUB_REF_NAME}
- name: Check out openlayers.github.io
uses: actions/checkout@v3
with:
repository: openlayers/openlayers.github.io
ssh-key: ${{ secrets.OPENLAYERS_GITHUB_IO_KEY }}
path: openlayers.github.io
- run: |
cp -r build/site/* openlayers.github.io/dist/
cd openlayers.github.io
git config user.name "$(git --no-pager log --format=format:'%an' -n 1)"
git config user.email "$(git --no-pager log --format=format:'%ae' -n 1)"
git add .
git commit -m "Website updates"
git push origin main

View File

@@ -1,21 +1,24 @@
name: Publish name: Publish Package
on: on:
push: push:
branches: branches:
- main - main
tags:
- 'v*.*.*'
permissions: permissions:
contents: read contents: read
jobs: jobs:
publish-npm: publish-branch:
if: startsWith(github.ref, 'refs/heads/')
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: actions/setup-node@v3 - uses: actions/setup-node@v3
with: with:
node-version: '16' node-version: '18'
registry-url: 'https://registry.npmjs.org' registry-url: 'https://registry.npmjs.org'
- name: Install dependencies - name: Install dependencies
run: npm ci run: npm ci
@@ -28,3 +31,23 @@ jobs:
npm publish --tag dev npm publish --tag dev
env: env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
publish-tag:
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
registry-url: 'https://registry.npmjs.org'
- name: Install dependencies
run: npm ci
- name: Assert Latest Release
run: node tasks/newest-tag.js --tag ${GITHUB_REF_NAME}
- name: Publish
run: |
npm run build-package
cd build/ol
npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}

21
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
name: Create Release
on:
push:
tags:
- 'v*.*.*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Build Release Assets
run: ./tasks/build-website.sh -l ${GITHUB_REF_NAME} -v ${GITHUB_REF_NAME}
- name: Create Release
run: node tasks/create-release.js --token ${{secrets.GITHUB_TOKEN}} --tag ${GITHUB_REF_NAME} --legacy build/${GITHUB_REF_NAME}-legacy.zip --site build/${GITHUB_REF_NAME}-site.zip

View File

@@ -78,4 +78,13 @@ mv build/legacy ${build}/en/${version}/
if [[ "${latest}" == "${version}" ]] ; then if [[ "${latest}" == "${version}" ]] ; then
echo "Copying to en/latest" echo "Copying to en/latest"
cp -r ${build}/en/${version} ${build}/en/latest cp -r ${build}/en/${version} ${build}/en/latest
echo "Building release artifacts"
pushd ${build}
zip -r ${OLDPWD}/build/${version}-site.zip . -x "en/${version}/*"
popd
pushd ${build}/en/${version}/legacy
zip -r ${OLDPWD}/build/${version}-legacy.zip .
popd
fi fi

107
tasks/create-release.js Normal file
View File

@@ -0,0 +1,107 @@
import esMain from 'es-main';
import yargs from 'yargs';
import {Octokit} from '@octokit/rest';
import {basename} from 'node:path';
import {hideBin} from 'yargs/helpers';
import {readFile, stat} from 'node:fs/promises';
/**
* @typedef {Object} Options
* @property {string} token The bearer token.
* @property {string} tag The tag.
* @property {boolean} draft Create a draft release.
* @property {boolean} notes Generate release notes.
* @property {string} site Path to zip archive with site contents.
* @property {string} legacy Path to zip archive with legacy build.
*/
const owner = 'openlayers';
const repo = 'openlayers';
/**
* Create a release.
* @param {Options} options The release options.
*/
async function createRelease(options) {
const client = new Octokit({
auth: options.token,
});
const response = await client.rest.repos.createRelease({
owner,
repo,
tag_name: options.tag,
generate_release_notes: options.notes,
draft: options.draft,
});
await uploadAsset(
client,
response.data,
options.site,
'Examples and docs (zip)'
);
await uploadAsset(
client,
response.data,
options.legacy,
'Legacy build (zip)'
);
}
async function uploadAsset(client, release, assetPath, label) {
const name = basename(assetPath);
const stats = await stat(assetPath);
const data = await readFile(assetPath);
await client.rest.repos.uploadReleaseAsset({
url: release.upload_url,
name,
label,
headers: {
'content-type': 'application/zip',
'content-length': stats.size,
},
data,
});
}
if (esMain(import.meta)) {
const options = yargs(hideBin(process.argv))
.option('token', {
describe: 'The token for auth',
type: 'string',
})
.demandOption('token')
.option('tag', {
describe: 'The release tag (e.g. v7.0.0)',
type: 'string',
})
.demandOption('tag')
.option('legacy-zip', {
describe: 'Path to the archive with the legacy build',
type: 'string',
})
.demandOption('legacy')
.option('site-zip', {
describe: 'Path to the archive with the site contents',
type: 'string',
})
.demandOption('site')
.option('draft', {
describe: 'Create a draft release',
type: 'boolean',
default: true,
})
.option('notes', {
describe: 'Generate release notes',
type: 'boolean',
default: true,
})
.parse();
createRelease(options).catch((err) => {
process.stderr.write(`${err.stack}\n`, () => process.exit(1));
});
}

View File

@@ -1,7 +1,8 @@
import esMain from 'es-main';
import semver from 'semver'; import semver from 'semver';
import {Octokit} from '@octokit/rest'; import {Octokit} from '@octokit/rest';
async function main() { export async function getLatestRelease() {
const client = new Octokit(); const client = new Octokit();
let latest = '0.0.0'; let latest = '0.0.0';
@@ -21,7 +22,15 @@ async function main() {
} }
); );
process.stdout.write(`v${latest}\n`); return latest;
} }
main(); if (esMain(import.meta)) {
getLatestRelease()
.then((latest) => {
process.stdout.write(`v${latest}\n`, () => process.exit(0));
})
.catch((err) => {
process.stderr.write(`${err.message}\n`, () => process.exit(1));
});
}

52
tasks/newest-tag.js Normal file
View File

@@ -0,0 +1,52 @@
import esMain from 'es-main';
import semver from 'semver';
import yargs from 'yargs';
import {getLatestRelease} from './get-latest-release.js';
import {hideBin} from 'yargs/helpers';
/**
* @typedef {Object} Options
* @property {string} tag The tag.
*/
/**
* Check if a tag is ahead of the latest release.
* @param {Options} options The options.
* @return {boolean} The provided tag is ahead of or equal to the latest release.
*/
async function main(options) {
const version = semver.valid(options.tag);
if (!version) {
return false;
}
const parsed = semver.parse(version);
if (parsed.prerelease.length) {
return false;
}
const latest = await getLatestRelease();
return semver.gte(version, latest);
}
if (esMain(import.meta)) {
const options = yargs(hideBin(process.argv))
.option('tag', {
describe: 'The tag to test (e.g. v1.2.3)',
type: 'string',
})
.demandOption('tag')
.parse();
main(options)
.then((newest) => {
if (newest) {
process.stdout.write('true\n', () => process.exit(0));
} else {
process.stderr.write('false\n', () => process.exit(1));
}
})
.catch((err) => {
process.stderr.write(`${err.stack}\n`, () => process.exit(1));
});
}