Skip to content

Commit 045ec47

Browse files
feat: added banner and update subscription check to make maintained actions free for public repos
1 parent f7acc3d commit 045ec47

10 files changed

Lines changed: 96 additions & 43 deletions

File tree

.github/workflows/actions_release.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ on:
66
tag:
77
description: "Tag for the release"
88
required: true
9+
node_version:
10+
description: "Specify Node.js version (e.g., '18', '20', 'lts/*')"
11+
required: false
12+
default: "24"
913

1014
permissions:
1115
contents: read
@@ -20,3 +24,4 @@ jobs:
2024
uses: step-security/reusable-workflows/.github/workflows/actions_release.yaml@v1
2125
with:
2226
tag: "${{ github.event.inputs.tag }}"
27+
node_version: "${{ github.event.inputs.node_version }}"

.github/workflows/audit_package.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ on:
1111
description: "Specify a base branch"
1212
required: false
1313
default: "main"
14+
node_version:
15+
description: "Specify Node.js version (e.g., '18', '20', 'lts/*')"
16+
required: false
17+
default: "24"
1418
schedule:
1519
- cron: "0 0 * * 1"
1620

@@ -20,6 +24,7 @@ jobs:
2024
with:
2125
force: ${{ inputs.force || false }}
2226
base_branch: ${{ inputs.base_branch || 'main' }}
27+
node_version: "${{ inputs.node_version || '24' }}"
2328

2429
permissions:
2530
contents: write

.github/workflows/auto_cherry_pick.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ on:
1111
description: "Run mode: cherry-pick or verify"
1212
required: false
1313
default: "cherry-pick"
14+
node_version:
15+
description: "Specify Node.js version (e.g., '18', '20', 'lts/*')"
16+
required: false
17+
default: "24"
1418

1519
pull_request:
1620
types: [opened, synchronize, labeled]
@@ -30,3 +34,4 @@ jobs:
3034
repo-name: "setup-xcode"
3135
base_branch: ${{ inputs.base_branch }}
3236
mode: ${{ github.event_name == 'pull_request' && 'verify' || inputs.mode }}
37+
node_version: "${{ inputs.node_version || '24' }}"

.github/workflows/guarddog.yml

Lines changed: 0 additions & 14 deletions
This file was deleted.

.github/workflows/workflow.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
- name: Set Node.JS
2525
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
2626
with:
27-
node-version: 20.x
27+
node-version: 24.x
2828

2929
- name: npm install
3030
run: npm install

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
[![StepSecurity Maintained Action](https://raw.githubusercontent.com/step-security/maintained-actions-assets/main/assets/maintained-action-banner.png)](https://docs.stepsecurity.io/actions/stepsecurity-maintained-actions)
2+
13
# setup-xcode
24
This action is intended to switch between pre-installed versions of Xcode for macOS images in GitHub Actions.
35

action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ inputs:
77
required: false
88
default: latest
99
runs:
10-
using: 'node20'
10+
using: 'node24'
1111
main: 'dist/index.js'
1212
branding:
1313
icon: 'code'

dist/index.js

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,42 @@ var __importStar = (this && this.__importStar) || function (mod) {
3131
};
3232
Object.defineProperty(exports, "__esModule", ({ value: true }));
3333
const core = __importStar(__nccwpck_require__(2186));
34+
const fs = __importStar(__nccwpck_require__(7147));
3435
const axios_1 = __importStar(__nccwpck_require__(8757));
3536
const xcode_selector_1 = __nccwpck_require__(8865);
3637
async function validateSubscription() {
37-
var _a;
38-
const API_URL = `https://agent.api.stepsecurity.io/v1/github/${process.env.GITHUB_REPOSITORY}/actions/subscription`;
38+
const eventPath = process.env.GITHUB_EVENT_PATH;
39+
let repoPrivate;
40+
if (eventPath && fs.existsSync(eventPath)) {
41+
const eventData = JSON.parse(fs.readFileSync(eventPath, 'utf8'));
42+
repoPrivate = eventData?.repository?.private;
43+
}
44+
const upstream = 'maxim-lobanov/setup-xcode';
45+
const action = process.env.GITHUB_ACTION_REPOSITORY;
46+
const docsUrl = 'https://docs.stepsecurity.io/actions/stepsecurity-maintained-actions';
47+
core.info('');
48+
core.info('\u001b[1;36mStepSecurity Maintained Action\u001b[0m');
49+
core.info(`Secure drop-in replacement for ${upstream}`);
50+
if (repoPrivate === false)
51+
core.info('\u001b[32m\u2713 Free for public repositories\u001b[0m');
52+
core.info(`\u001b[36mLearn more:\u001b[0m ${docsUrl}`);
53+
core.info('');
54+
if (repoPrivate === false)
55+
return;
56+
const serverUrl = process.env.GITHUB_SERVER_URL || 'https://github.com';
57+
const body = { action: action || '' };
58+
if (serverUrl !== 'https://github.com')
59+
body.ghes_server = serverUrl;
3960
try {
40-
await axios_1.default.get(API_URL, { timeout: 3000 });
61+
await axios_1.default.post(`https://agent.api.stepsecurity.io/v1/github/${process.env.GITHUB_REPOSITORY}/actions/maintained-actions-subscription`, body, { timeout: 3000 });
4162
}
4263
catch (error) {
43-
if ((0, axios_1.isAxiosError)(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 403) {
44-
core.error("Subscription is not valid. Reach out to support@stepsecurity.io");
64+
if ((0, axios_1.isAxiosError)(error) && error.response?.status === 403) {
65+
core.error(`\u001b[1;31mThis action requires a StepSecurity subscription for private repositories.\u001b[0m`);
66+
core.error(`\u001b[31mLearn how to enable a subscription: ${docsUrl}\u001b[0m`);
4567
process.exit(1);
4668
}
47-
else {
48-
core.info("Timeout or API not reachable. Continuing to next step.");
49-
}
69+
core.info('Timeout or API not reachable. Continuing to next step.');
5070
}
5171
}
5272
async function run() {
@@ -127,7 +147,6 @@ class XcodeSelector {
127147
return xcodeVersions.sort((first, second) => semver.compare(second.version, first.version));
128148
}
129149
findVersion(versionSpec) {
130-
var _a;
131150
const availableVersions = this.getAllVersions();
132151
if (availableVersions.length === 0) {
133152
return null;
@@ -144,9 +163,9 @@ class XcodeSelector {
144163
isStable = false;
145164
versionSpec = versionSpec.slice(0, -betaSuffix.length);
146165
}
147-
return ((_a = availableVersions
166+
return (availableVersions
148167
.filter(ver => ver.stable === isStable)
149-
.find(ver => semver.satisfies(ver.version, versionSpec))) !== null && _a !== void 0 ? _a : null);
168+
.find(ver => semver.satisfies(ver.version, versionSpec)) ?? null);
150169
}
151170
setVersion(xcodeVersion) {
152171
if (!fs.existsSync(xcodeVersion.path)) {
@@ -219,9 +238,8 @@ const getInstalledXcodeApps = () => {
219238
};
220239
exports.getInstalledXcodeApps = getInstalledXcodeApps;
221240
const getXcodeReleaseType = (xcodeRootPath) => {
222-
var _a, _b;
223241
const licenseInfo = (0, exports.parsePlistFile)(path.join(xcodeRootPath, "Contents", "Resources", "LicenseInfo.plist"));
224-
const licenseType = (_b = (_a = licenseInfo === null || licenseInfo === void 0 ? void 0 : licenseInfo.licenseType) === null || _a === void 0 ? void 0 : _a.toString()) === null || _b === void 0 ? void 0 : _b.toLowerCase();
242+
const licenseType = licenseInfo?.licenseType?.toString()?.toLowerCase();
225243
if (!licenseType) {
226244
core.debug("Unable to determine Xcode version type based on license plist");
227245
core.debug("Xcode License plist doesn't contain 'licenseType' property");
@@ -231,10 +249,9 @@ const getXcodeReleaseType = (xcodeRootPath) => {
231249
};
232250
exports.getXcodeReleaseType = getXcodeReleaseType;
233251
const getXcodeVersionInfo = (xcodeRootPath) => {
234-
var _a, _b;
235252
const versionInfo = (0, exports.parsePlistFile)(path.join(xcodeRootPath, "Contents", "version.plist"));
236-
const xcodeVersion = semver.coerce((_a = versionInfo === null || versionInfo === void 0 ? void 0 : versionInfo.CFBundleShortVersionString) === null || _a === void 0 ? void 0 : _a.toString());
237-
const xcodeBuildNumber = (_b = versionInfo === null || versionInfo === void 0 ? void 0 : versionInfo.ProductBuildVersion) === null || _b === void 0 ? void 0 : _b.toString();
253+
const xcodeVersion = semver.coerce(versionInfo?.CFBundleShortVersionString?.toString());
254+
const xcodeBuildNumber = versionInfo?.ProductBuildVersion?.toString();
238255
if (!xcodeVersion || !semver.valid(xcodeVersion)) {
239256
core.debug(`Unable to retrieve Xcode version info on path '${xcodeRootPath}'`);
240257
return null;

src/setup-xcode.ts

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,53 @@
11
import * as core from "@actions/core";
2+
import * as fs from "fs";
23
import axios, { isAxiosError } from "axios";
34
import { XcodeSelector } from "./xcode-selector";
45

56
async function validateSubscription(): Promise<void> {
6-
const API_URL = `https://agent.api.stepsecurity.io/v1/github/${process.env.GITHUB_REPOSITORY}/actions/subscription`;
7+
const eventPath = process.env.GITHUB_EVENT_PATH
8+
let repoPrivate: boolean | undefined
79

8-
try {
9-
await axios.get(API_URL, { timeout: 3000 });
10-
} catch (error) {
11-
if (isAxiosError(error) && error.response?.status === 403) {
12-
core.error("Subscription is not valid. Reach out to support@stepsecurity.io");
13-
process.exit(1);
14-
} else {
15-
core.info("Timeout or API not reachable. Continuing to next step.");
16-
}
10+
if (eventPath && fs.existsSync(eventPath)) {
11+
const eventData = JSON.parse(fs.readFileSync(eventPath, 'utf8'))
12+
repoPrivate = eventData?.repository?.private
13+
}
14+
15+
const upstream = 'maxim-lobanov/setup-xcode'
16+
const action = process.env.GITHUB_ACTION_REPOSITORY
17+
const docsUrl =
18+
'https://docs.stepsecurity.io/actions/stepsecurity-maintained-actions'
19+
20+
core.info('')
21+
core.info('\u001b[1;36mStepSecurity Maintained Action\u001b[0m')
22+
core.info(`Secure drop-in replacement for ${upstream}`)
23+
if (repoPrivate === false)
24+
core.info('\u001b[32m\u2713 Free for public repositories\u001b[0m')
25+
core.info(`\u001b[36mLearn more:\u001b[0m ${docsUrl}`)
26+
core.info('')
27+
28+
if (repoPrivate === false) return
29+
30+
const serverUrl = process.env.GITHUB_SERVER_URL || 'https://github.com'
31+
const body: Record<string, string> = {action: action || ''}
32+
if (serverUrl !== 'https://github.com') body.ghes_server = serverUrl
33+
try {
34+
await axios.post(
35+
`https://agent.api.stepsecurity.io/v1/github/${process.env.GITHUB_REPOSITORY}/actions/maintained-actions-subscription`,
36+
body,
37+
{timeout: 3000}
38+
)
39+
} catch (error) {
40+
if (isAxiosError(error) && error.response?.status === 403) {
41+
core.error(
42+
`\u001b[1;31mThis action requires a StepSecurity subscription for private repositories.\u001b[0m`
43+
)
44+
core.error(
45+
`\u001b[31mLearn how to enable a subscription: ${docsUrl}\u001b[0m`
46+
)
47+
process.exit(1)
1748
}
49+
core.info('Timeout or API not reachable. Continuing to next step.')
50+
}
1851
}
1952

2053
async function run(): Promise<void> {

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"compilerOptions": {
3-
"target": "ES2019",
3+
"target": "ES2022",
44
"module": "commonjs",
55
"outDir": "./lib",
66
"rootDir": "./src",

0 commit comments

Comments
 (0)