зеркало из https://github.com/Azure/autorest.git
Internal: Migrate to using rush publish and rush change (#3809)
This commit is contained in:
Родитель
3b80bf9506
Коммит
4dbb3dca5e
|
@ -1,76 +0,0 @@
|
|||
const { spawn } = require("child_process");
|
||||
const { readFileSync } = require("fs");
|
||||
const { resolve } = require("path");
|
||||
|
||||
function read(filename) {
|
||||
const txt = readFileSync(filename, "utf8")
|
||||
.replace(/\r/gm, "")
|
||||
.replace(/\n/gm, "«")
|
||||
.replace(/\/\*.*?\*\//gm, "")
|
||||
.replace(/«/gm, "\n")
|
||||
.replace(/\s+\/\/.*/g, "");
|
||||
return JSON.parse(txt);
|
||||
}
|
||||
|
||||
const repo = `${__dirname}/..`;
|
||||
|
||||
const rush = read(`${repo}/rush.json`);
|
||||
const pjs = {};
|
||||
|
||||
function forEachProject(onEach) {
|
||||
// load all the projects
|
||||
for (const each of rush.projects) {
|
||||
const packageName = each.packageName;
|
||||
const projectFolder = resolve(`${repo}/${each.projectFolder}`);
|
||||
const project = JSON.parse(readFileSync(`${projectFolder}/package.json`));
|
||||
onEach(packageName, projectFolder, project);
|
||||
}
|
||||
}
|
||||
|
||||
function npmForEach(cmd) {
|
||||
let count = 0;
|
||||
let exitCode = 0;
|
||||
const result = {};
|
||||
const procs = [];
|
||||
const t1 = process.uptime() * 100;
|
||||
forEachProject((name, location, project) => {
|
||||
// checks for the script first
|
||||
if (project.scripts[cmd]) {
|
||||
count++;
|
||||
const proc = spawn("npm", ["--silent", "run", cmd], { cwd: location, shell: true, stdio: "inherit" });
|
||||
procs.push(proc);
|
||||
result[name] = {
|
||||
name,
|
||||
location,
|
||||
project,
|
||||
proc,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
procs.forEach((proc) =>
|
||||
proc.on("close", (code, signal) => {
|
||||
count--;
|
||||
exitCode += code;
|
||||
|
||||
if (count === 0) {
|
||||
const t2 = process.uptime() * 100;
|
||||
|
||||
console.log("---------------------------------------------------------");
|
||||
if (exitCode !== 0) {
|
||||
console.log(` Done : command '${cmd}' - ${Math.floor(t2 - t1) / 100} s -- Errors ${exitCode} `);
|
||||
} else {
|
||||
console.log(` Done : command '${cmd}' - ${Math.floor(t2 - t1) / 100} s -- No Errors `);
|
||||
}
|
||||
console.log("---------------------------------------------------------");
|
||||
process.exit(exitCode);
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
module.exports.forEachProject = forEachProject;
|
||||
module.exports.npm = npmForEach;
|
||||
module.exports.projectCount = rush.projects.length;
|
|
@ -1,2 +0,0 @@
|
|||
// Runs the npm run command on each project that has it.
|
||||
require("./for-each").npm(process.argv[2]);
|
|
@ -1,44 +0,0 @@
|
|||
# publishes a package to NPM (passed in as $(pkg) variable)
|
||||
# you can also customize the tag used for NPM with the $(tag) variable (defaults to 'latest')
|
||||
# if you want to set a secondary tag on the package (like V2), set the $(altTag) variable
|
||||
|
||||
trigger:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: "ubuntu-latest"
|
||||
|
||||
steps:
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: "12.x"
|
||||
displayName: "Install Node.js"
|
||||
|
||||
- script: |
|
||||
# ensure latest npm is installed
|
||||
npm install -g npm
|
||||
npm config set //registry.npmjs.org/:_authToken=$(azure-sdk-npm-token)
|
||||
|
||||
# grab the file specified
|
||||
wget $(pkg)
|
||||
rc=$?; if [ $rc -ne 0 ]; then exit $rc ; fi
|
||||
|
||||
# determine the tag
|
||||
npmTag="latest"
|
||||
if [ -n "$(tag)" ]; then
|
||||
npmTag=$(tag)
|
||||
fi
|
||||
|
||||
# publish it to npm
|
||||
for file in *.tgz
|
||||
do
|
||||
npm publish $file --tag $npmTag --access public
|
||||
rc=$?; if [ $rc -ne 0 ]; then exit $rc ; fi
|
||||
|
||||
# set the alternate tag, if applicable
|
||||
if [ -n "$(altTag)" ]; then
|
||||
tar -zxvf $file
|
||||
cd package/
|
||||
npm dist-tag add $(npm show . name)@$(npm show . version) --tag $(altTag)
|
||||
fi
|
||||
done
|
|
@ -1,42 +0,0 @@
|
|||
const { exec } = require("child_process");
|
||||
const { writeFileSync } = require("fs");
|
||||
const { forEachProject, projectCount } = require("./for-each");
|
||||
|
||||
let count = projectCount;
|
||||
|
||||
function updateVersion(name, project, location, patch) {
|
||||
const origJson = JSON.stringify(project, null, 2);
|
||||
|
||||
// update the third digit
|
||||
const verInfo = project.version.split(".");
|
||||
verInfo[2] = patch;
|
||||
project.version = verInfo.join(".");
|
||||
|
||||
// write the file if it's changed
|
||||
const newJson = JSON.stringify(project, null, 2);
|
||||
if (origJson !== newJson) {
|
||||
console.log(`Writing project '${name}' version to '${project.version}' in '${location}'`);
|
||||
writeFileSync(`${location}/package.json`, newJson);
|
||||
}
|
||||
|
||||
count--;
|
||||
if (count === 0) {
|
||||
// last one!
|
||||
// call sync-versions
|
||||
require("./sync-versions");
|
||||
}
|
||||
}
|
||||
|
||||
if (process.argv[2] === "--reset") {
|
||||
forEachProject((name, location, project) => {
|
||||
updateVersion(name, project, location, 0);
|
||||
});
|
||||
} else {
|
||||
// Sets the patch version on each package.json in the project.
|
||||
forEachProject((name, location, project) => {
|
||||
exec(`git rev-list --parents HEAD --count --full-history .`, { cwd: location }, (o, stdout) => {
|
||||
const patch = parseInt(stdout.trim()) + (Number(project.patchOffset) || -1);
|
||||
updateVersion(name, project, location, patch);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
const { readFileSync, writeFileSync } = require("fs");
|
||||
|
||||
function read(filename) {
|
||||
const txt = readFileSync(filename, "utf8")
|
||||
.replace(/\r/gm, "")
|
||||
.replace(/\n/gm, "«")
|
||||
.replace(/\/\*.*?\*\//gm, "")
|
||||
.replace(/«/gm, "\n")
|
||||
.replace(/\s+\/\/.*/g, "");
|
||||
return JSON.parse(txt);
|
||||
}
|
||||
|
||||
const packageList = {};
|
||||
const rush = read(`${__dirname}/../rush.json`);
|
||||
const pjs = {};
|
||||
|
||||
function writeIfChanged(filename, content) {
|
||||
const orig = JSON.parse(readFileSync(filename));
|
||||
const origJson = JSON.stringify(orig, null, 2);
|
||||
const json = JSON.stringify(content, null, 2);
|
||||
|
||||
if (origJson !== json) {
|
||||
console.log(`Writing updated file '${filename}'`);
|
||||
writeFileSync(filename, json);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function versionToInt(ver) {
|
||||
let v = ver
|
||||
.replace(/[^\d\.]/g, "")
|
||||
.split(".")
|
||||
.slice(0, 3);
|
||||
while (v.length < 3) {
|
||||
v.unshift(0);
|
||||
}
|
||||
let n = 0;
|
||||
for (let i = 0; i < v.length; i++) {
|
||||
n = n + 2 ** (i * 16) * parseInt(v[v.length - 1 - i]);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
function setPeerDependencies(dependencies) {
|
||||
for (const dep in dependencies) {
|
||||
const ref = pjs[dep];
|
||||
if (ref) {
|
||||
if (dependencies[dep] !== `~${ref.version}`) {
|
||||
console.log(`updating peer depedency ${dep} to ~${ref.version}`);
|
||||
dependencies[dep] = `~${ref.version}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function recordDeps(dependencies) {
|
||||
for (const packageName in dependencies) {
|
||||
const packageVersion = dependencies[packageName];
|
||||
if (packageList[packageName]) {
|
||||
// same version?
|
||||
if (packageList[packageName] === packageVersion) {
|
||||
continue;
|
||||
}
|
||||
console.log(`${packageName} has ['${packageList[packageName]}','${packageVersion}']`);
|
||||
|
||||
// pick the higher one
|
||||
const v = versionToInt(packageVersion);
|
||||
|
||||
if (v === 0) {
|
||||
console.error(`Unparsed version ${packageName}:${packageVersion}`);
|
||||
process.exit(1);
|
||||
}
|
||||
const v2 = versionToInt(packageList[packageName]);
|
||||
if (v > v2) {
|
||||
packageList[packageName] = packageVersion;
|
||||
}
|
||||
} else {
|
||||
packageList[packageName] = packageVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
function fixDeps(pj, dependencies) {
|
||||
for (const packageName in dependencies) {
|
||||
if (dependencies[packageName] !== packageList[packageName]) {
|
||||
console.log(`updating ${pj}:${packageName} from '${dependencies[packageName]}' to '${packageList[packageName]}'`);
|
||||
dependencies[packageName] = packageList[packageName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// load all the projects
|
||||
for (const each of rush.projects) {
|
||||
const packageName = each.packageName;
|
||||
const projectFolder = each.projectFolder;
|
||||
pjs[packageName] = JSON.parse(readFileSync(`${__dirname}/../${projectFolder}/package.json`));
|
||||
}
|
||||
|
||||
// verify that peer dependencies are the same version as they are building.
|
||||
for (const pj of Object.getOwnPropertyNames(pjs)) {
|
||||
const each = pjs[pj];
|
||||
setPeerDependencies(each.dependencies);
|
||||
setPeerDependencies(each.devDependencies);
|
||||
if (each["static-link"]) {
|
||||
setPeerDependencies(each["static-link"].dependencies);
|
||||
}
|
||||
}
|
||||
|
||||
// now compare to see if someone has an exnternal package with different version
|
||||
// than everyone else.
|
||||
for (const pj of Object.getOwnPropertyNames(pjs)) {
|
||||
const each = pjs[pj];
|
||||
recordDeps(each.dependencies);
|
||||
recordDeps(each.devDependencies);
|
||||
if (each["static-link"]) {
|
||||
recordDeps(each["static-link"].dependencies);
|
||||
}
|
||||
}
|
||||
|
||||
for (const pj of Object.getOwnPropertyNames(pjs)) {
|
||||
const each = pjs[pj];
|
||||
fixDeps(pj, each.dependencies);
|
||||
fixDeps(pj, each.devDependencies);
|
||||
if (each["static-link"]) {
|
||||
fixDeps(pj, each["static-link"].dependencies);
|
||||
}
|
||||
}
|
||||
var changed = 0;
|
||||
|
||||
// write out the results.
|
||||
for (const each of rush.projects) {
|
||||
const packageName = each.packageName;
|
||||
const projectFolder = each.projectFolder;
|
||||
if (writeIfChanged(`${__dirname}/../${projectFolder}/package.json`, pjs[packageName])) {
|
||||
changed++;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
console.log(`Updated ${changed} files.`);
|
||||
} else {
|
||||
console.log("No changes made");
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
var cp = require("child_process");
|
||||
|
||||
require("./for-each").forEachProject((packageName, projectFolder, project) => {
|
||||
if (project.scripts.watch) {
|
||||
console.log(`npm run watch {cwd: ${__dirname}/../${projectFolder}}`);
|
||||
const proc = cp.spawn("npm", ["run", "watch"], { cwd: projectFolder, shell: true, stdio: "inherit" });
|
||||
proc.on("error", (c, s) => {
|
||||
console.log(packageName);
|
||||
console.error(c);
|
||||
console.error(s);
|
||||
});
|
||||
proc.on("exit", (c, s) => {
|
||||
console.log(packageName);
|
||||
console.error(c);
|
||||
console.error(s);
|
||||
});
|
||||
proc.on("message", (c, s) => {
|
||||
console.log(packageName);
|
||||
console.error(c);
|
||||
console.error(s);
|
||||
});
|
||||
}
|
||||
});
|
|
@ -0,0 +1,114 @@
|
|||
# Autorest Development
|
||||
|
||||
## Requirements
|
||||
|
||||
- `node` (LTS recommended)
|
||||
|
||||
Optional recommendation:
|
||||
|
||||
- VSCode with the following extensions:
|
||||
|
||||
- Prettier
|
||||
- ESLint
|
||||
- EditorConfig
|
||||
|
||||
## First build
|
||||
|
||||
1. Install [rush.js](https://rushjs.io/pages/intro/get_started/) using
|
||||
|
||||
```bash
|
||||
npm install -g @microsoft/rush
|
||||
```
|
||||
|
||||
2. Install dependencies
|
||||
|
||||
```bash
|
||||
rush update
|
||||
```
|
||||
|
||||
3. Build
|
||||
|
||||
```bash
|
||||
rush build
|
||||
|
||||
# or to do a force rebuild.
|
||||
rush rebuild
|
||||
```
|
||||
|
||||
## Run in watch mode
|
||||
|
||||
When working on autorest it is recommended to have the compiler run in watch mode. This means that on file changes typescript will automatically recompile and produce the output.
|
||||
|
||||
```bash
|
||||
# Run for all packages.
|
||||
rush watch
|
||||
# Run for a specific package.
|
||||
npm run watch
|
||||
```
|
||||
|
||||
## Test
|
||||
|
||||
Test framework we used is [jest](https://jestjs.io/)
|
||||
|
||||
To run the test you have 2 options:
|
||||
|
||||
1. Run all the tests using
|
||||
|
||||
```bash
|
||||
rush test:ci
|
||||
```
|
||||
|
||||
2. Run individual project tests(Recommended when working on test)
|
||||
|
||||
```bash
|
||||
# Go to the package directory
|
||||
cd packages/<type>/<package>/
|
||||
|
||||
# Run test in interactive mode
|
||||
npm test
|
||||
|
||||
# Alternatively you can run them once with coverage(Same as rush test:ci)
|
||||
npm run test:ci
|
||||
```
|
||||
|
||||
## Other commands
|
||||
|
||||
- Linting
|
||||
|
||||
```bash
|
||||
# Run for all packages.
|
||||
rush lint
|
||||
# Run for a specific package.
|
||||
npm run lint
|
||||
```
|
||||
|
||||
- Cleaning
|
||||
|
||||
```bash
|
||||
# Run for all packages.
|
||||
rush clean
|
||||
# Run for a specific package.
|
||||
npm run clean
|
||||
```
|
||||
|
||||
## Use your local changes
|
||||
|
||||
You can tell autorest to use your local changes.
|
||||
|
||||
- For `@autorest/core`, use the `--version` option
|
||||
|
||||
```bash
|
||||
autorest --version:<path-to-repo>/packages/extensions/core
|
||||
```
|
||||
|
||||
- For `@autorest/modelerfour`, use the `--use` option
|
||||
|
||||
```bash
|
||||
autorest --use:<path-to-repo>/packages/extensions/modelerfour
|
||||
```
|
||||
|
||||
- For `autorest itself`, change the command
|
||||
|
||||
```bash
|
||||
node <path-to-repo>/packages/apps/autorest/entrypoints/app.js
|
||||
```
|
|
@ -0,0 +1,14 @@
|
|||
# Autorest publishing
|
||||
|
||||
This is the instruction to publish a new autorest package.
|
||||
|
||||
## Track changes
|
||||
|
||||
Autorest pull request validation will check that changes are being documented using `rush change --verify`.
|
||||
This means that if the pull request include some changes to any packages you will have to run `rush change` to interactively describe what the changes are and how they affect the package(Major, minor, patch).
|
||||
|
||||
## Release
|
||||
|
||||
If you want to release an update you will then have to run `rush publish`. This will take all pending change files created with `rush change`, update the changelog and bump the package(s) version.
|
||||
|
||||
Then in the Pull Request make sure to add the `Publish` label to tell the validation that this is meant to publish and it will ignore the change check above.
|
|
@ -0,0 +1,4 @@
|
|||
# Autorest Core developer docs
|
||||
|
||||
- [Development](./development.md)
|
||||
- [Publishing](./publishing.md)
|
|
@ -12,7 +12,8 @@ jobs:
|
|||
- job: main
|
||||
displayName: "Build and test"
|
||||
steps:
|
||||
- template: ./build.yaml
|
||||
- template: ./templates/verify-changes.yaml
|
||||
- template: ./templates/build.yaml
|
||||
|
||||
- script: npx @microsoft/rush test:ci -v
|
||||
displayName: Test
|
|
@ -10,19 +10,11 @@ pool:
|
|||
vmImage: "ubuntu-latest"
|
||||
|
||||
steps:
|
||||
- template: ./build.yaml
|
||||
parameters:
|
||||
setVersion: true
|
||||
- template: ./templates/build.yaml
|
||||
|
||||
- script: npx @microsoft/rush publish --publish --pack --include-all
|
||||
displayName: Pack packages
|
||||
|
||||
- script: |
|
||||
# publish the packages (tag as preview by default)
|
||||
echo "//registry.npmjs.org/:_authToken=$(azure-sdk-npm-token)" > ./.npmrc
|
||||
for file in common/temp/artifacts/packages/*.tgz
|
||||
do
|
||||
echo "Trying to publish $file:"
|
||||
npm publish $file --tag latest --access public --no-git-checks || echo no-worries
|
||||
done
|
||||
NPM_AUTH_TOKEN="$(azure-sdk-npm-token)" rush publish --apply --include-all --set-access-level public
|
||||
displayName: Publish packages
|
|
@ -1,19 +1,10 @@
|
|||
# Template for building projects
|
||||
parameters:
|
||||
- name: setVersion # Update version of packages.
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
steps:
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: "14.x"
|
||||
displayName: "Install Node.js"
|
||||
|
||||
- ${{ if eq(parameters.setVersion, true) }}:
|
||||
- script: npx @microsoft/rush set-versions
|
||||
displayName: Set package versions
|
||||
|
||||
- script: |
|
||||
npm install -g npm
|
||||
npx @microsoft/rush update
|
|
@ -0,0 +1,16 @@
|
|||
# Steps to verify there is undocumented changes in the PR.
|
||||
|
||||
steps:
|
||||
- script: |
|
||||
LABEL_NAME=Publish
|
||||
LABEL_URL=https://api.github.com/repos/$BUILD_REPOSITORY_ID/issues/$SYSTEM_PULLREQUEST_PULLREQUESTNUMBER/labels
|
||||
|
||||
echo "Getting labels using $LABEL_URL"
|
||||
if curl -s "$LABEL_URL" | grep "\"name\": \"$LABEL_NAME\""
|
||||
then
|
||||
echo "Publish label was included in the PR, won't be checking for changelog."
|
||||
else
|
||||
npx @microsoft/rush change --verify || { echo '\nIf you run the rush publish command locally and meant to publish the changes, add the publish label to the pr.' ; exit 1; }
|
||||
fi
|
||||
displayName: Verify change logs
|
||||
condition: eq(variables['Build.Reason'], 'PullRequest') # only run step if it is a PR
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
"name": "autorest",
|
||||
"version": "3.0.0",
|
||||
"patchOffset": 5110,
|
||||
"version": "3.0.6335",
|
||||
"description": "The AutoRest tool generates client libraries for accessing RESTful web services. Input to AutoRest is an OpenAPI spec that describes the REST API.",
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
"name": "@autorest/core",
|
||||
"version": "3.0.0",
|
||||
"patchOffset": 5136,
|
||||
"version": "3.0.6369",
|
||||
"description": "AutoRest core module",
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
"name": "@autorest/modelerfour",
|
||||
"version": "4.15.0",
|
||||
"patchOffset": -765,
|
||||
"version": "4.15.454",
|
||||
"description": "AutoRest Modeler Version Four (component)",
|
||||
"directories": {
|
||||
"doc": "docs"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
"name": "@autorest/codemodel",
|
||||
"version": "4.14.0",
|
||||
"patchOffset": -1219,
|
||||
"version": "4.14.2",
|
||||
"description": "AutoRest code model library",
|
||||
"directories": {
|
||||
"doc": "docs"
|
||||
|
|
|
@ -10,6 +10,12 @@ AutoRest is an open source tool -- if you need assistance, first check the docum
|
|||
|
||||
View our [docs readme][docs_readme] as a starting point to find both general information and language-generator specific information
|
||||
|
||||
## Contributing
|
||||
|
||||
### Contributing guide
|
||||
|
||||
Check our [internal developer docs](./docs/internal/readme.md) to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to Autorest.
|
||||
|
||||
### Code of Conduct
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
|
Загрузка…
Ссылка в новой задаче