Skip to content

Commit

Permalink
Merge pull request #205 from axios/v1.x
Browse files Browse the repository at this point in the history
Create a new pull request by comparing changes across two branches
  • Loading branch information
GulajavaMinistudio committed Nov 9, 2023
2 parents 40c082d + 7009715 commit 41dad1e
Show file tree
Hide file tree
Showing 30 changed files with 1,185 additions and 588 deletions.
41 changes: 41 additions & 0 deletions .github/workflows/notify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: notify

on:
#workflow_run:
# workflows: ["publish"]
# types:
# - completed
#repository_dispatch:
# types: [ notify ]
release:
types: [ published ]
workflow_dispatch:
inputs:
tag:
required: true
jobs:
notify:
runs-on: ubuntu-latest
#if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
steps:
#- name: Dump GitHub context
# env:
# GITHUB_CONTEXT: ${{ toJson(github) }}
# run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: git config
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 18
cache: npm
- run: npm ci
- name: Notify published PRs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: node ./bin/actions/notify_published.js --tag ${{ github.event.inputs.tag || github.event.release.tag_name }}
7 changes: 5 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ jobs:
publish:
if: github.event_name == 'workflow_dispatch' || (github.event.pull_request.merged == true && github.event.pull_request.head.label == 'axios:release')
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- name: "Release PR info"
if: github.event_name != 'workflow_dispatch'
Expand All @@ -22,7 +25,7 @@ jobs:
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
- uses: actions/setup-node@v3
with:
node-version: 16
node-version: 18
registry-url: https://registry.npmjs.org/
- run: npm ci
- name: get-npm-version
Expand Down Expand Up @@ -50,6 +53,6 @@ jobs:
${{ steps.extract-release-notes.outputs.release_notes }}
############# NPM RELEASE ##############
- name: Publish the release to NPM
run: npm publish
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

## [1.6.1](https://github.com/axios/axios/compare/v1.6.0...v1.6.1) (2023-11-08)


### Bug Fixes

* **formdata:** fixed content-type header normalization for non-standard browser environments; ([#6056](https://github.com/axios/axios/issues/6056)) ([dd465ab](https://github.com/axios/axios/commit/dd465ab22bbfa262c6567be6574bf46a057d5288))
* **platform:** fixed emulated browser detection in node.js environment; ([#6055](https://github.com/axios/axios/issues/6055)) ([3dc8369](https://github.com/axios/axios/commit/3dc8369e505e32a4e12c22f154c55fd63ac67fbb))

### Contributors to this release

- <img src="https://avatars.githubusercontent.com/u/12586868?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+432/-65 (#6059 #6056 #6055 )")
- <img src="https://avatars.githubusercontent.com/u/3982806?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Fabian Meyer](https://github.com/meyfa "+5/-2 (#5835 )")

# [1.6.0](https://github.com/axios/axios/compare/v1.5.1...v1.6.0) (2023-10-26)


Expand Down
131 changes: 131 additions & 0 deletions bin/GithubAPI.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import util from "util";
import cp from "child_process";
import {parseVersion} from "./helpers/parser.js";
import githubAxios from "./githubAxios.js";
import memoize from 'memoizee';

const exec = util.promisify(cp.exec);

export default class GithubAPI {
constructor(owner, repo) {
if (!owner) {
throw new Error('repo owner must be specified');
}

if (!repo) {
throw new Error('repo must be specified');
}

this.repo = repo;
this.owner = owner;
this.axios = githubAxios.create({
baseURL: `https://api.github.com/repos/${this.owner}/${this.repo}/`,
})
}

async createComment(issue, body) {
return (await this.axios.post(`/issues/${issue}/comments`, {body})).data;
}

async getComments(issue, {desc = false, per_page= 100, page = 1} = {}) {
return (await this.axios.get(`/issues/${issue}/comments`, {params: {direction: desc ? 'desc' : 'asc', per_page, page}})).data;
}

async getComment(id) {
return (await this.axios.get(`/issues/comments/${id}`)).data;
}

async updateComment(id, body) {
return (await this.axios.patch(`/issues/comments/${id}`, {body})).data;
}

async appendLabels(issue, labels) {
return (await this.axios.post(`/issues/${issue}/labels`, {labels})).data;
}

async getUser(user) {
return (await githubAxios.get(`/users/${user}`)).data;
}

async isCollaborator(user) {
try {
return (await this.axios.get(`/collaborators/${user}`)).status === 204;
} catch (e) {

}
}

async deleteLabel(issue, label) {
return (await this.axios.delete(`/issues/${issue}/labels/${label}`)).data;
}

async getIssue(issue) {
return (await this.axios.get(`/issues/${issue}`)).data;
}

async getPR(issue) {
return (await this.axios.get(`/pulls/${issue}`)).data;
}

async getIssues({state= 'open', labels, sort = 'created', desc = false, per_page = 100, page = 1}) {
return (await this.axios.get(`/issues`, {params: {state, labels, sort, direction: desc ? 'desc' : 'asc', per_page, page}})).data;
}

async updateIssue(issue, data) {
return (await this.axios.patch(`/issues/${issue}`, data)).data;
}

async closeIssue(issue) {
return this.updateIssue(issue, {
state: "closed"
})
}

async getReleases({per_page = 30, page= 1} = {}) {
return (await this.axios.get(`/releases`, {params: {per_page, page}})).data;
}

async getRelease(release = 'latest') {
return (await this.axios.get(parseVersion(release) ? `/releases/tags/${release}` : `/releases/${release}`)).data;
}

async getTags({per_page = 30, page= 1} = {}) {
return (await this.axios.get(`/tags`, {params: {per_page, page}})).data;
}

async reopenIssue(issue) {
return this.updateIssue(issue, {
state: "open"
})
}

static async getTagRef(tag) {
try {
return (await exec(`git show-ref --tags "refs/tags/${tag}"`)).stdout.split(' ')[0];
} catch (e) {
}
}

static async getLatestTag() {
try{
const {stdout} = await exec(`git for-each-ref refs/tags --sort=-taggerdate --format='%(refname)' --count=1`);

return stdout.split('/').pop();
} catch (e) {}
}

static normalizeTag(tag){
return tag ? 'v' + tag.replace(/^v/, '') : '';
}
}

const {prototype} = GithubAPI;

['getUser', 'isCollaborator'].forEach(methodName => {
prototype[methodName] = memoize(prototype[methodName], { promise: true })
});

['get', 'post', 'put', 'delete', 'isAxiosError'].forEach((method) => prototype[method] = function(...args){
return this.axios[method](...args);
});

128 changes: 128 additions & 0 deletions bin/RepoBot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import GithubAPI from "./GithubAPI.js";
import api from './api.js';
import Handlebars from "handlebars";
import fs from "fs/promises";
import {colorize} from "./helpers/colorize.js";
import {getReleaseInfo} from "./contributors.js";
import path from "path";
import {fileURLToPath} from "url";

const __dirname = path.dirname(fileURLToPath(import.meta.url));

const NOTIFY_PR_TEMPLATE = path.resolve(__dirname, '../templates/pr_published.hbs');

const normalizeTag = (tag) => tag ? 'v' + tag.replace(/^v/, '') : '';

const GITHUB_BOT_LOGIN = 'github-actions[bot]';

const skipCollaboratorPRs = true;

class RepoBot {
constructor(options) {
const {
owner, repo,
templates
} = options || {};

this.templates = Object.assign({
published: NOTIFY_PR_TEMPLATE
}, templates);

this.github = api || new GithubAPI(owner, repo);

this.owner = this.github.owner;
this.repo = this.github.repo;
}

async addComment(targetId, message) {
return this.github.createComment(targetId, message);
}

async notifyPRPublished(id, tag) {
let pr;

try {
pr = await this.github.getPR(id);
} catch (err) {
if(err.response?.status === 404) {
throw new Error(`PR #${id} not found (404)`);
}

throw err;
}

tag = normalizeTag(tag);

const {merged, labels, user: {login, type}} = pr;

const isBot = type === 'Bot';

if (!merged) {
return false
}

await this.github.appendLabels(id, [tag]);

if (isBot || labels.find(({name}) => name === 'automated pr') || (skipCollaboratorPRs && await this.github.isCollaborator(login))) {
return false;
}

const comments = await this.github.getComments(id, {desc: true});

const comment = comments.find(
({body, user}) => user.login === GITHUB_BOT_LOGIN && body.indexOf('published in') >= 0
)

if (comment) {
console.log(colorize()`Release comment [${comment.html_url}] already exists in #${pr.id}`);
return false;
}

const author = await this.github.getUser(login);

author.isBot = isBot;

const message = await this.constructor.renderTemplate(this.templates.published, {
id,
author,
release: {
tag,
url: `https://github.com/${this.owner}/${this.repo}/releases/tag/${tag}`
}
});

return await this.addComment(id, message);
}

async notifyPublishedPRs(tag) {
tag = normalizeTag(tag);

const release = await getReleaseInfo(tag);

if (!release) {
throw Error(colorize()`Can't get release info for ${tag}`);
}

const {merges} = release;

console.log(colorize()`Found ${merges.length} PRs in ${tag}:`);

let i = 0;

for (const pr of merges) {
try {
console.log(colorize()`${i++}) Notify PR #${pr.id}`)
const result = await this.notifyPRPublished(pr.id, tag);
console.log('✔️', result ? 'Label, comment' : 'Label');
} catch (err) {
console.warn(colorize('green', 'red')`❌ Failed notify PR ${pr.id}: ${err.message}`);
}
}
}

static async renderTemplate(template, data) {
return Handlebars.compile(String(await fs.readFile(template)))(data);
}
}

export default RepoBot;
28 changes: 28 additions & 0 deletions bin/actions/notify_published.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import minimist from "minimist";
import RepoBot from '../RepoBot.js';
import fs from 'fs/promises';

const argv = minimist(process.argv.slice(2));
console.log(argv);

let {tag} = argv;

(async() => {
if (!tag || tag === true) {
const {version} = JSON.parse((await fs.readFile('./package.json')).toString());

tag = 'v' + version;
} else if (typeof tag !== 'string') {

throw new Error('tag must be a string');
}

const bot = new RepoBot();

try {
await bot.notifyPublishedPRs(tag);
} catch (err) {
console.warn('Error:', err.message);
}
})();

3 changes: 3 additions & 0 deletions bin/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import GithubAPI from "./GithubAPI.js";

export default new GithubAPI('axios', 'axios');
Loading

0 comments on commit 41dad1e

Please sign in to comment.