Unverified Commit 6ea3bb38 authored by Samruddhi Khandale's avatar Samruddhi Khandale Committed by GitHub

Update generate-docs Action with OCI syntax (#74)

* Update docs with OCI spec changes

* reference to version `:1` than `:latest`

* nit

* sync generate-doc changes

* add workflow condition

* revert features README changes

* address comments
parent d10390a1
...@@ -24,6 +24,14 @@ inputs: ...@@ -24,6 +24,14 @@ inputs:
required: false required: false
default: '' default: ''
description: "Relative path to the 'src' folder containing dev container 'feature(s)'" description: "Relative path to the 'src' folder containing dev container 'feature(s)'"
oci-registry:
required: false
default: "ghcr.io"
description: "Name of the OCI registry that implements the OCI Artifact Distribution Specification"
features-namespace:
required: false
default: "<owner>/<repo>"
description: "A unique indentifier for the collection of features"
# 'template' options # 'template' options
base-path-to-templates: base-path-to-templates:
......
...@@ -53,7 +53,7 @@ const FEATURES_README_TEMPLATE = ` ...@@ -53,7 +53,7 @@ const FEATURES_README_TEMPLATE = `
\`\`\`json \`\`\`json
"features": { "features": {
"#{Nwo}/#{Id}@#{VersionTag}": { "#{Registry}/#{Namespace}/#{Id}:#{Version}": {
"version": "latest" "version": "latest"
} }
} }
...@@ -76,9 +76,9 @@ const TEMPLATE_README_TEMPLATE = ` ...@@ -76,9 +76,9 @@ const TEMPLATE_README_TEMPLATE = `
#{OptionsTable} #{OptionsTable}
`; `;
function generateFeaturesDocumentation(basePath) { function generateFeaturesDocumentation(basePath, ociRegistry, namespace) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
yield _generateDocumentation(basePath, FEATURES_README_TEMPLATE, 'devcontainer-feature.json'); yield _generateDocumentation(basePath, FEATURES_README_TEMPLATE, 'devcontainer-feature.json', ociRegistry, namespace);
}); });
} }
exports.generateFeaturesDocumentation = generateFeaturesDocumentation; exports.generateFeaturesDocumentation = generateFeaturesDocumentation;
...@@ -88,7 +88,7 @@ function generateTemplateDocumentation(basePath) { ...@@ -88,7 +88,7 @@ function generateTemplateDocumentation(basePath) {
}); });
} }
exports.generateTemplateDocumentation = generateTemplateDocumentation; exports.generateTemplateDocumentation = generateTemplateDocumentation;
function _generateDocumentation(basePath, readmeTemplate, metadataFile) { function _generateDocumentation(basePath, readmeTemplate, metadataFile, ociRegistry = '', namespace = '') {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const directories = fs.readdirSync(basePath); const directories = fs.readdirSync(basePath);
yield Promise.all(directories.map((f) => __awaiter(this, void 0, void 0, function* () { yield Promise.all(directories.map((f) => __awaiter(this, void 0, void 0, function* () {
...@@ -114,13 +114,15 @@ function _generateDocumentation(basePath, readmeTemplate, metadataFile) { ...@@ -114,13 +114,15 @@ function _generateDocumentation(basePath, readmeTemplate, metadataFile) {
return; return;
} }
const srcInfo = (0, utils_1.getGitHubMetadata)(); const srcInfo = (0, utils_1.getGitHubMetadata)();
const ref = srcInfo.ref;
const owner = srcInfo.owner; const owner = srcInfo.owner;
const repo = srcInfo.repo; const repo = srcInfo.repo;
// Add tag if parseable // Add version
let versionTag = 'latest'; let version = 'latest';
if (ref && ref.includes('refs/tags/')) { const parsedVersion = parsedJson === null || parsedJson === void 0 ? void 0 : parsedJson.version;
versionTag = ref.replace('refs/tags/', ''); if (parsedVersion) {
// example - 1.0.0
const splitVersion = parsedVersion.split('.');
version = splitVersion[0];
} }
const generateOptionsMarkdown = () => { const generateOptionsMarkdown = () => {
const options = parsedJson === null || parsedJson === void 0 ? void 0 : parsedJson.options; const options = parsedJson === null || parsedJson === void 0 ? void 0 : parsedJson.options;
...@@ -148,8 +150,9 @@ function _generateDocumentation(basePath, readmeTemplate, metadataFile) { ...@@ -148,8 +150,9 @@ function _generateDocumentation(basePath, readmeTemplate, metadataFile) {
.replace('#{Description}', (_a = parsedJson.description) !== null && _a !== void 0 ? _a : '') .replace('#{Description}', (_a = parsedJson.description) !== null && _a !== void 0 ? _a : '')
.replace('#{OptionsTable}', generateOptionsMarkdown()) .replace('#{OptionsTable}', generateOptionsMarkdown())
// Features Only // Features Only
.replace('#{Nwo}', `${owner}/${repo}`) .replace('#{Registry}', ociRegistry)
.replace('#{VersionTag}', versionTag) .replace('#{Namespace}', namespace == '<owner>/<repo>' ? `${owner}/${repo}` : namespace)
.replace('#{Version}', version)
// Templates Only // Templates Only
.replace('#{ManifestName}', (_c = (_b = parsedJson === null || parsedJson === void 0 ? void 0 : parsedJson.image) === null || _b === void 0 ? void 0 : _b.manifest) !== null && _c !== void 0 ? _c : '') .replace('#{ManifestName}', (_c = (_b = parsedJson === null || parsedJson === void 0 ? void 0 : parsedJson.image) === null || _b === void 0 ? void 0 : _b.manifest) !== null && _c !== void 0 ? _c : '')
.replace('#{RepoUrl}', urlToConfig); .replace('#{RepoUrl}', urlToConfig);
...@@ -232,6 +235,8 @@ function run() { ...@@ -232,6 +235,8 @@ function run() {
}; };
const featuresBasePath = core.getInput('base-path-to-features'); const featuresBasePath = core.getInput('base-path-to-features');
const templatesBasePath = core.getInput('base-path-to-templates'); const templatesBasePath = core.getInput('base-path-to-templates');
const ociRegistry = core.getInput('oci-registry');
const namespace = core.getInput('features-namespace');
let featuresMetadata = undefined; let featuresMetadata = undefined;
let templatesMetadata = undefined; let templatesMetadata = undefined;
// -- Package Release Artifacts // -- Package Release Artifacts
...@@ -246,7 +251,7 @@ function run() { ...@@ -246,7 +251,7 @@ function run() {
// -- Generate Documentation // -- Generate Documentation
if (shouldGenerateDocumentation && featuresBasePath) { if (shouldGenerateDocumentation && featuresBasePath) {
core.info('Generating documentation for features...'); core.info('Generating documentation for features...');
yield (0, generateDocs_1.generateFeaturesDocumentation)(featuresBasePath); yield (0, generateDocs_1.generateFeaturesDocumentation)(featuresBasePath, ociRegistry, namespace);
} }
if (shouldGenerateDocumentation && templatesBasePath) { if (shouldGenerateDocumentation && templatesBasePath) {
core.info('Generating documentation for templates...'); core.info('Generating documentation for templates...');
......
...@@ -46,7 +46,7 @@ const FEATURES_README_TEMPLATE = ` ...@@ -46,7 +46,7 @@ const FEATURES_README_TEMPLATE = `
\`\`\`json \`\`\`json
"features": { "features": {
"#{Nwo}/#{Id}@#{VersionTag}": { "#{Registry}/#{Namespace}/#{Id}:#{Version}": {
"version": "latest" "version": "latest"
} }
} }
...@@ -69,9 +69,9 @@ const TEMPLATE_README_TEMPLATE = ` ...@@ -69,9 +69,9 @@ const TEMPLATE_README_TEMPLATE = `
#{OptionsTable} #{OptionsTable}
`; `;
function generateFeaturesDocumentation(basePath) { function generateFeaturesDocumentation(basePath, ociRegistry, namespace) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
yield _generateDocumentation(basePath, FEATURES_README_TEMPLATE, 'devcontainer-feature.json'); yield _generateDocumentation(basePath, FEATURES_README_TEMPLATE, 'devcontainer-feature.json', ociRegistry, namespace);
}); });
} }
exports.generateFeaturesDocumentation = generateFeaturesDocumentation; exports.generateFeaturesDocumentation = generateFeaturesDocumentation;
...@@ -81,7 +81,7 @@ function generateTemplateDocumentation(basePath) { ...@@ -81,7 +81,7 @@ function generateTemplateDocumentation(basePath) {
}); });
} }
exports.generateTemplateDocumentation = generateTemplateDocumentation; exports.generateTemplateDocumentation = generateTemplateDocumentation;
function _generateDocumentation(basePath, readmeTemplate, metadataFile) { function _generateDocumentation(basePath, readmeTemplate, metadataFile, ociRegistry = '', namespace = '') {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const directories = fs.readdirSync(basePath); const directories = fs.readdirSync(basePath);
yield Promise.all(directories.map((f) => __awaiter(this, void 0, void 0, function* () { yield Promise.all(directories.map((f) => __awaiter(this, void 0, void 0, function* () {
...@@ -107,13 +107,15 @@ function _generateDocumentation(basePath, readmeTemplate, metadataFile) { ...@@ -107,13 +107,15 @@ function _generateDocumentation(basePath, readmeTemplate, metadataFile) {
return; return;
} }
const srcInfo = (0, utils_1.getGitHubMetadata)(); const srcInfo = (0, utils_1.getGitHubMetadata)();
const ref = srcInfo.ref;
const owner = srcInfo.owner; const owner = srcInfo.owner;
const repo = srcInfo.repo; const repo = srcInfo.repo;
// Add tag if parseable // Add version
let versionTag = 'latest'; let version = 'latest';
if (ref && ref.includes('refs/tags/')) { const parsedVersion = parsedJson === null || parsedJson === void 0 ? void 0 : parsedJson.version;
versionTag = ref.replace('refs/tags/', ''); if (parsedVersion) {
// example - 1.0.0
const splitVersion = parsedVersion.split('.');
version = splitVersion[0];
} }
const generateOptionsMarkdown = () => { const generateOptionsMarkdown = () => {
const options = parsedJson === null || parsedJson === void 0 ? void 0 : parsedJson.options; const options = parsedJson === null || parsedJson === void 0 ? void 0 : parsedJson.options;
...@@ -141,8 +143,9 @@ function _generateDocumentation(basePath, readmeTemplate, metadataFile) { ...@@ -141,8 +143,9 @@ function _generateDocumentation(basePath, readmeTemplate, metadataFile) {
.replace('#{Description}', (_a = parsedJson.description) !== null && _a !== void 0 ? _a : '') .replace('#{Description}', (_a = parsedJson.description) !== null && _a !== void 0 ? _a : '')
.replace('#{OptionsTable}', generateOptionsMarkdown()) .replace('#{OptionsTable}', generateOptionsMarkdown())
// Features Only // Features Only
.replace('#{Nwo}', `${owner}/${repo}`) .replace('#{Registry}', ociRegistry)
.replace('#{VersionTag}', versionTag) .replace('#{Namespace}', namespace == '<owner>/<repo>' ? `${owner}/${repo}` : namespace)
.replace('#{Version}', version)
// Templates Only // Templates Only
.replace('#{ManifestName}', (_c = (_b = parsedJson === null || parsedJson === void 0 ? void 0 : parsedJson.image) === null || _b === void 0 ? void 0 : _b.manifest) !== null && _c !== void 0 ? _c : '') .replace('#{ManifestName}', (_c = (_b = parsedJson === null || parsedJson === void 0 ? void 0 : parsedJson.image) === null || _b === void 0 ? void 0 : _b.manifest) !== null && _c !== void 0 ? _c : '')
.replace('#{RepoUrl}', urlToConfig); .replace('#{RepoUrl}', urlToConfig);
......
...@@ -59,6 +59,8 @@ function run() { ...@@ -59,6 +59,8 @@ function run() {
}; };
const featuresBasePath = core.getInput('base-path-to-features'); const featuresBasePath = core.getInput('base-path-to-features');
const templatesBasePath = core.getInput('base-path-to-templates'); const templatesBasePath = core.getInput('base-path-to-templates');
const ociRegistry = core.getInput('oci-registry');
const namespace = core.getInput('features-namespace');
let featuresMetadata = undefined; let featuresMetadata = undefined;
let templatesMetadata = undefined; let templatesMetadata = undefined;
// -- Package Release Artifacts // -- Package Release Artifacts
...@@ -73,7 +75,7 @@ function run() { ...@@ -73,7 +75,7 @@ function run() {
// -- Generate Documentation // -- Generate Documentation
if (shouldGenerateDocumentation && featuresBasePath) { if (shouldGenerateDocumentation && featuresBasePath) {
core.info('Generating documentation for features...'); core.info('Generating documentation for features...');
yield (0, generateDocs_1.generateFeaturesDocumentation)(featuresBasePath); yield (0, generateDocs_1.generateFeaturesDocumentation)(featuresBasePath, ociRegistry, namespace);
} }
if (shouldGenerateDocumentation && templatesBasePath) { if (shouldGenerateDocumentation && templatesBasePath) {
core.info('Generating documentation for templates...'); core.info('Generating documentation for templates...');
......
...@@ -8,7 +8,7 @@ on: ...@@ -8,7 +8,7 @@ on:
jobs: jobs:
generate: generate:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, 'no-ci') && !contains(github.event.head_commit.message, 'CI ignore')" if: "github.ref == 'refs/heads/main' && !contains(github.event.head_commit.message, 'no-ci') && !contains(github.event.head_commit.message, 'CI ignore')"
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
......
...@@ -67,21 +67,21 @@ See the relevant feature's README for supported options. ...@@ -67,21 +67,21 @@ See the relevant feature's README for supported options.
"name": "my-project-devcontainer", "name": "my-project-devcontainer",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu", // Any generic, debian-based image. "image": "mcr.microsoft.com/devcontainers/base:ubuntu", // Any generic, debian-based image.
features: { features: {
"devcontainers/features/go@latest": { "ghcr.io/devcontainers/features/go:1": {
"version": "1.18" "version": "1.18"
}, },
"devcontainers/features/docker-in-docker@latest": { "ghcr.io/devcontainers/features/docker-in-docker:1": {
"version": "latest", "version": "latest",
"moby": true "moby": true
} }
} }
``` ```
The `@latest` version annotation is added implicitly if omitted. To pin to a specific [release tag](https://github.com/devcontainers/features/releases), append it to the end of the feature. The `:latest` version annotation is added implicitly if omitted. To pin to a specific package version ([example](https://github.com/devcontainers/features/pkgs/container/features/go/versions)), append it to the end of the feature.
```jsonc ```jsonc
features: { features: {
"devcontainers/features/go@v0.0.2": { "ghcr.io/devcontainers/features/go:1": {
"version": "1.18" "version": "1.18"
}, },
``` ```
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment