Skip to content
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
16 changes: 5 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,12 @@ jobs:
with:
registry-url: 'https://registry.npmjs.org/'
node-version-file: 'package.json'
- name: Build
run: make build

- name: Prettier
run: make prettier

- name: fail if files changed
- name: Show versions
run: |
if ! git diff --quiet --exit-code ; then
echo "Please run 'make build' and 'make prettier' locally and commit the changes."
exit 1
fi
echo "Node version: $(node --version)"
echo "npm version: $(npm --version)"
- name: CI Check
run: make ci-check

- name: Test
run: make test
45 changes: 42 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,21 +1,60 @@


.PHONY: clean
clean:
rm -rf dist
rm -rf coverage
rm -rf examples/*.js
find . -name "*.tsbuildinfo" -delete

.PHONY: deps
deps:
npm i
npm install

.PHONY: build
build: deps
build: clean deps
npm run build

.PHONY: test
test: build
npm run test

.PHONY: prettier
prettier:
prettier: deps
npm run prettier

.PHONY: prettier-check
prettier-check: deps
npx prettier --config .prettierrc 'src/**/*.ts' --check

.PHONY: ci-check
ci-check: deps build prettier
@echo "Checking for uncommitted changes..."
@if ! git diff --quiet --exit-code; then \
echo "❌ Error: Files were modified by 'npm install', build, or prettier"; \
echo "Modified files:"; \
git diff --name-only; \
echo ""; \
if git diff --quiet package-lock.json 2>/dev/null; then \
echo "Please run 'make build' and 'make prettier' locally and commit the changes."; \
else \
echo "package-lock.json was modified. Checking if it's just peer metadata differences..."; \
git diff package-lock.json > /tmp/package-lock.diff; \
if grep -q '^[+-].*"peer":' /tmp/package-lock.diff && ! grep -qvE '^[+-].*"peer":|^[+-]---|^[+]\+\+\+|^@@' /tmp/package-lock.diff; then \
echo "⚠️ Only peer metadata differences detected. These are harmless but should be normalized."; \
echo " Run 'npm install --package-lock-only' locally and commit the updated package-lock.json"; \
else \
echo "package-lock.json has significant differences (not just peer metadata)"; \
echo "Please run 'npm install' locally and commit the updated package-lock.json"; \
fi; \
echo ""; \
echo "Differences in package-lock.json:"; \
git diff package-lock.json | head -100; \
fi; \
exit 1; \
fi
@echo "✅ No uncommitted changes detected"

.PHONY: publish
publish: test
npm publish
6,374 changes: 3,193 additions & 3,181 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Can interact with the vendor portal api!",
"scripts": {
"build": "rm -rf dist && tsc --build",
"prettier": "prettier --config .prettierrc 'src/**/*.ts' --write",
"prettier": "npx prettier --config .prettierrc 'src/**/*.ts' --write",
"test": "npx jest --coverage --verbose --setupFiles ./pacts/configuration.ts",
"create-object-store": "rm -rf examples/*.js && tsc examples/create-object-store.ts && node examples/create-object-store.js",
"create-postgres": "rm -rf examples/*.js && tsc examples/create-postgres.ts && node examples/create-postgres.js",
Expand Down
60 changes: 60 additions & 0 deletions scripts/verify-ci-match.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/bin/bash
# Script to verify local environment matches CI exactly

set -e

echo "=== Verifying local matches CI ==="
echo ""

# Check npm and node versions
echo "1. Checking versions..."
NPM_VERSION=$(npm --version)
NODE_VERSION=$(node --version)
echo " npm: $NPM_VERSION"
echo " node: $NODE_VERSION"
echo ""

# Clean state
echo "2. Cleaning node_modules and dist..."
rm -rf node_modules dist coverage

# Install exactly as CI does (npm install, not npm ci)
echo "3. Installing with 'npm install' (as CI does)..."
npm install

# Check if package-lock.json was modified
if ! git diff --quiet --exit-code package-lock.json; then
echo "❌ package-lock.json was modified by npm install!"
echo " This means it's out of sync with package.json"
echo " Differences:"
git diff package-lock.json | head -50
echo ""
echo " To fix:"
echo " 1. Review the changes above"
echo " 2. Commit the updated package-lock.json"
exit 1
fi
echo "✅ package-lock.json is up to date"
echo ""

# Build and check for changes
echo "5. Building..."
npm run build

echo "6. Running prettier..."
npm run prettier

echo "7. Checking for uncommitted changes..."
if ! git diff --quiet --exit-code; then
echo "❌ Files were modified:"
git diff --name-only
echo ""
echo " Differences:"
git diff | head -100
exit 1
fi

echo "✅ Everything matches CI!"
echo ""
echo "Your local environment matches what CI will produce."

36 changes: 21 additions & 15 deletions src/channels.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,18 @@ describe("ChannelsService", () => {
});

describe("pollForAirgapReleaseStatus", () => {
const mockServer = mockttp.getLocal();
let mockServer: mockttp.Mockttp;
const apiClient = new VendorPortalApi();
apiClient.apiToken = "abcd1234";
apiClient.endpoint = "http://localhost:8080";
// Start your mock server
beforeEach(() => {
mockServer.start(8080);

beforeEach(async () => {
mockServer = mockttp.getLocal();
await mockServer.start();
apiClient.endpoint = "http://localhost:" + mockServer.port;
});
afterEach(async () => {
await mockServer.stop();
});
afterEach(() => mockServer.stop());

it("should poll for airgapped release status until it reaches the expected status", async () => {
const releaseData = {
Expand All @@ -105,23 +108,26 @@ describe("pollForAirgapReleaseStatus", () => {
]
};

await mockServer.forGet("/app/1234abcd/channel/1/releases").thenReply(200, JSON.stringify(releaseData));
await mockServer.forGet("/app/1234abcd/channel/1/releases").once().thenReply(200, JSON.stringify(releaseData));

const releaseResult = await pollForAirgapReleaseStatus(apiClient, "1234abcd", "1", 0, "built");
expect(releaseResult).toEqual("built");
});
});

describe("getDownloadUrlAirgapBuildRelease", () => {
const mockServer = mockttp.getLocal();
let mockServer: mockttp.Mockttp;
const apiClient = new VendorPortalApi();
apiClient.apiToken = "abcd1234";
apiClient.endpoint = "http://localhost:8081";
// Start your mock server
beforeEach(() => {
mockServer.start(8081);

beforeEach(async () => {
mockServer = mockttp.getLocal();
await mockServer.start();
apiClient.endpoint = "http://localhost:" + mockServer.port;
});
afterEach(async () => {
await mockServer.stop();
});
afterEach(() => mockServer.stop());

it("should get the download URL for an airgap build release", async () => {
const releaseData = {
Expand All @@ -137,8 +143,8 @@ describe("getDownloadUrlAirgapBuildRelease", () => {
url: "https://s3.amazonaws.com/airgap.replicated.com/xxxxxxxxx/7.airgap?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=xxxxxx%2F20250317%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date="
};

await mockServer.forGet("/app/1234abcd/channel/1/releases").thenReply(200, JSON.stringify(releaseData));
await mockServer.forGet("/app/1234abcd/channel/1/airgap/download-url").withQuery({ channelSequence: 1 }).thenReply(200, JSON.stringify(downloadUrlData));
await mockServer.forGet("/app/1234abcd/channel/1/releases").once().thenReply(200, JSON.stringify(releaseData));
await mockServer.forGet("/app/1234abcd/channel/1/airgap/download-url").withQuery({ channelSequence: 1 }).once().thenReply(200, JSON.stringify(downloadUrlData));

const downloadUrlResult = await getDownloadUrlAirgapBuildRelease(apiClient, "1234abcd", "1", 0);
expect(downloadUrlResult).toEqual("https://s3.amazonaws.com/airgap.replicated.com/xxxxxxxxx/7.airgap?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=xxxxxx%2F20250317%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=");
Expand Down
Loading