Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GHA to publish VSIX package #34

Merged
merged 2 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/create_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: Checkout code
- name: Checkout repository
uses: actions/checkout@v3

- name: Install Node.js
Expand All @@ -27,7 +27,6 @@ jobs:
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');
const packageVersion = require('./package.json').version;
const response = await github.rest.repos.createRelease({
owner: context.repo.owner,
Expand Down
110 changes: 110 additions & 0 deletions .github/workflows/publish_release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: Publish Extension Package for GitHub Release

on:
workflow_dispatch:
inputs:
release-tag-name:
description: 'Release Tag Name / Version'
required: true

jobs:
publish-release-extension:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: '16.x'

- name: Validate tag name
id: validate_tag_name
uses: actions/github-script@v6
with:
script: |
let tagNameValue = "${{ github.event.inputs.release-tag-name }}";
console.log(`Input tag name / version: ${tagNameValue}`);
// Take the 'v' off to validate the SemVer version.
if (tagNameValue.startsWith('v')) {
tagNameValue = tagNameValue.slice(1);
}

// Officially supported SemVer version syntax regex.
// See https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
const validVersionRegex = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
if (!validVersionRegex.test(tagNameValue)) {
throw new Error(`'${tagNameValue}' is not a valid version string.`);
}

// Put the 'v' back on, as our release tags are formatted as 'v'x.y.z.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice comments!

tagNameValue = `v${tagNameValue}`;
console.log(`Resultant tag name used: ${tagNameValue}`);
return tagNameValue;

- name: Get package name for tag
id: get_package_name
uses: actions/github-script@v6
with:
script: |
const packageName = require('./package.json').name;
const tagName = ${{ steps.validate_tag_name.outputs.result }}
const packageVersion = tagName.slice(1); // Take the 'v' off the tag.
const vsixPackageName = `${packageName}-${packageVersion}.vsix`;
console.log(`Package name that will be used: ${vsixPackageName}`);
return vsixPackageName;

- name: Get release and associated VSIX asset
id: get_release_and_asset
uses: actions/github-script@v6
with:
script: |
const releaseTagName = ${{ steps.validate_tag_name.outputs.result }};
const vsixPackageName = ${{ steps.get_package_name.outputs.result }};
const response = await github.rest.repos.getReleaseByTag({
owner: context.repo.owner,
repo: context.repo.repo,
tag: releaseTagName
});
if (!response.data) {
throw new Error(`Release not found for tag: ${releaseTagName}`);
}
const release = response.data;
const asset = release.assets.find(asset => asset.name === vsixPackageName);
if (!asset) {
throw new Error(`Asset '${vsixPackageName}' not found for release tag: ${releaseTagName}`);
}
const assetResponse = await github.rest.repos.getReleaseAsset({
owner: context.repo.owner,
repo: context.repo.repo,
asset_id: asset.id,
});
return assetResponse.url;

- name: Download asset
id: download_asset
uses: actions/github-script@v6
with:
script: |
const assetUrl = ${{ steps.get_release_and_asset.outputs.result }};
const vsixPackageName = ${{ steps.get_package_name.outputs.result }};
console.log(`assetUrl: ${assetUrl}`);
const response = await github.request(`GET ${assetUrl}`, {
headers: {
'Accept': 'application/octet-stream'
},
responseType: 'arraybuffer'
});
if (response.status !== 200) {
throw new Error(`Failed to download '${vsixPackageName}': ${response.status}`);
}
const fs = require('fs');
fs.writeFileSync(vsixPackageName, Buffer.from(response.data, 'binary'));

- name: Publish to VSCode Marketplace
env:
VSCE_PERSONAL_ACCESS_TOKEN: ${{ secrets.VSCE_PERSONAL_ACCESS_TOKEN }}
run: |
npx vsce publish -p ${{ env.VSCE_PERSONAL_ACCESS_TOKEN }} --packagePath ${{ steps.get_package_name.outputs.result }}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

heh... a lot of this GHA flow is new to me...so LGTM!