ci: add publish action (#3210)
This commit is contained in:
parent
d22f7e680e
commit
eff1fe3131
65
.github/workflows/publish.yml
vendored
Normal file
65
.github/workflows/publish.yml
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
name: Netlify CMS Publish
|
||||
|
||||
on:
|
||||
repository_dispatch:
|
||||
|
||||
jobs:
|
||||
check-permission:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
SENDER: ${{ github.event.sender.login }}
|
||||
ALLOWED_LOGINS_TO_PUBLISH: ${{ secrets.ALLOWED_LOGINS_TO_PUBLISH }}
|
||||
steps:
|
||||
- name: 'Check Permission To Publish'
|
||||
run: |
|
||||
if [[ "$SENDER" =~ ^$ALLOWED_LOGINS_TO_PUBLISH$ ]]; then
|
||||
echo "$SENDER is allowed to publish"
|
||||
exit 0
|
||||
else
|
||||
echo "$SENDER is not allowed to publish"
|
||||
exit 1
|
||||
fi
|
||||
publish:
|
||||
needs: check-permission
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [12.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.cache/yarn
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles(format('{0}{1}', github.workspace, '/yarn.lock')) }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
- name: update yarn to latest version
|
||||
run: |
|
||||
sudo apt update && sudo apt install yarn
|
||||
|
||||
- name: Install Dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Switch to master branch
|
||||
run: git checkout master
|
||||
|
||||
- name: Setup Git User
|
||||
run: |
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
|
||||
- name: Publish Netlify CMS
|
||||
uses: erezrokah/2fa-with-slack-action@v1.0.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NPM_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||
SLACK_TOKEN: ${{secrets.SLACK_TOKEN}}
|
||||
CONVERSATION_ID: ${{secrets.CONVERSATION_ID}}
|
||||
PUBLISH_COMMAND: "yarn\npublish:ci:github"
|
||||
CODE_PATTERN: 'Enter OTP'
|
71
functions/publish.js
Normal file
71
functions/publish.js
Normal file
@ -0,0 +1,71 @@
|
||||
const crypto = require('crypto');
|
||||
const axios = require('axios');
|
||||
|
||||
const verifySignature = event => {
|
||||
const timestamp = Number(event.headers['x-slack-request-timestamp']);
|
||||
const time = Math.floor(Date.now() / 1000);
|
||||
if (time - timestamp > 60 * 5) {
|
||||
throw new Error(`Failed verifying signature. Timestamp too old '${timestamp}'`);
|
||||
}
|
||||
const body = event.body;
|
||||
const sigString = `v0:${timestamp}:${body}`;
|
||||
const actualSignature = event.headers['x-slack-signature'];
|
||||
const secret = process.env.SLACK_SIGNING_SECRET;
|
||||
|
||||
const hash = crypto
|
||||
.createHmac('sha256', secret)
|
||||
.update(sigString, 'utf8')
|
||||
.digest('hex');
|
||||
|
||||
const expectedSignature = `v0=${hash}`;
|
||||
|
||||
const signaturesMatch = crypto.timingSafeEqual(
|
||||
Buffer.from(actualSignature, 'utf8'),
|
||||
Buffer.from(expectedSignature, 'utf8'),
|
||||
);
|
||||
|
||||
if (!signaturesMatch) {
|
||||
throw new Error(
|
||||
`Signatures don't match. Expected: '${expectedSignature}', actual: '${actualSignature}'`,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
exports.handler = async function(event) {
|
||||
try {
|
||||
console.log(JSON.stringify(event, null, 2));
|
||||
verifySignature(event);
|
||||
|
||||
const params = new URLSearchParams(event.body);
|
||||
const command = params.get('command');
|
||||
const userId = params.get('user_id');
|
||||
|
||||
const allowedUsers = (process.env.ALLOWED_USERS || '').split(',');
|
||||
if (!allowedUsers.includes(userId)) {
|
||||
throw new Error(`User '${params.get('user_name')}' is not allowed to run command`);
|
||||
}
|
||||
|
||||
const expectedCommand = process.env.PUBLISH_COMMAND;
|
||||
if (expectedCommand && expectedCommand == command) {
|
||||
const githubToken = process.env.GITHUB_TOKEN;
|
||||
const repo = process.env.GITHUB_REPO;
|
||||
await axios({
|
||||
headers: { Authorization: `token ${githubToken}` },
|
||||
method: 'post',
|
||||
url: `https://api.github.com/repos/${repo}/dispatches`,
|
||||
data: { event_type: 'on-demand-github-action' },
|
||||
});
|
||||
const message = 'Dispatched event to GitHub';
|
||||
return { status: 200, body: message };
|
||||
} else {
|
||||
throw new Error(`Command is not allowed. Expected: ${expectedCommand}. Actual: ${command}`);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
const response = {
|
||||
body: 'Unauthorized',
|
||||
status: 401,
|
||||
};
|
||||
return response;
|
||||
}
|
||||
};
|
@ -41,12 +41,14 @@
|
||||
"format:prettier": "prettier \"{{packages,scripts,website}/**/,}*.{js,jsx,ts,tsx,css}\"",
|
||||
"publish": "run-s publish:before-manual-version publish:after-manual-version",
|
||||
"publish:ci": "run-s publish:prepare \"publish:version --yes\" build publish:push-git \"publish:from-git --yes\"",
|
||||
"publish:ci:github": "run-s publish:prepare \"publish:version --yes\" build publish:push-git:ci \"publish:from-git --yes\"",
|
||||
"publish:before-manual-version": "run-s publish:prepare publish:version",
|
||||
"publish:after-manual-version": "run-s build publish:push",
|
||||
"publish:prepare": "run-s bootstrap test",
|
||||
"publish:version": "lerna version --no-push",
|
||||
"publish:push": "run-s publish:push-git publish:from-git",
|
||||
"publish:push-git": "git push --follow-tags",
|
||||
"publish:push-git:ci": "git push \"https://$GITHUB_ACTOR:$GITHUB_TOKEN@github.com/$GITHUB_REPOSITORY.git\" --follow-tags",
|
||||
"publish:from-git": "lerna publish from-git --pre-dist-tag beta",
|
||||
"publish:dry-run": "run-s \"publish:version --no-git-tag-version\"",
|
||||
"publish:prerelease": "run-s publish:prerelease:before-manual-version publish:after-manual-version",
|
||||
|
Loading…
x
Reference in New Issue
Block a user