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
29 changes: 0 additions & 29 deletions .github/workflows/zz-integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -791,35 +791,6 @@ jobs:
test "${{ steps.deploy.outputs.exit-code }}" = "1"
test "${{ steps.deploy.outputs.drift-detected }}" = "true"

state-deploy-community:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Flyway
uses: red-gate/setup-flyway@v3
with:
edition: community
i-agree-to-the-eula: true
- name: Run state deploy
id: deploy
uses: ./state/deploy
with:
target-url: jdbc:sqlite:state-target.db
script-path: deployments/D__deployment.sql
working-directory: sample-projects/sqlite
- name: Test outputs
shell: bash
run: |
set -euo pipefail
echo "Exit code: ${{ steps.deploy.outputs.exit-code }}"
echo "Drift detected: ${{ steps.deploy.outputs.drift-detected }}"
test "${{ steps.deploy.outputs.exit-code }}" = "0"
test "${{ steps.deploy.outputs.drift-detected }}" = ""

state-deploy-no-comparison-support:
strategy:
matrix:
Expand Down
7 changes: 5 additions & 2 deletions state/deploy/dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10509,12 +10509,16 @@ await (async () => {
rn("Flyway is not installed or not in PATH. Run red-gate/setup-flyway before this action.");
return;
}
if (e.edition !== "enterprise") {
rn(`State-based deployments require Flyway Enterprise edition (current edition: ${e.edition}).`);
return;
}
let t = En();
if (!t.targetEnvironment && !t.targetUrl) {
rn("Either \"target-environment\" or \"target-url\" must be provided for Flyway to connect to a database.");
return;
}
if (Dn(t), e.edition === "enterprise") if (t.skipDriftCheck) on("Skipping drift check: \"skip-drift-check\" set to true"), t.saveSnapshot = !0;
if (Dn(t), t.skipDriftCheck) on("Skipping drift check: \"skip-drift-check\" set to true"), t.saveSnapshot = !0;
else {
let { driftDetected: e, comparisonSupported: n } = await On(t);
if (e) {
Expand All @@ -10523,7 +10527,6 @@ await (async () => {
}
t.saveSnapshot = n;
}
else on(`Skipping drift check as edition is not Enterprise (actual edition: ${e.edition}).`);
await wn(t);
} catch (e) {
e instanceof Error ? rn(e.message) : rn(String(e));
Expand Down
28 changes: 15 additions & 13 deletions state/deploy/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ const run = async (): Promise<void> => {
core.setFailed("Flyway is not installed or not in PATH. Run red-gate/setup-flyway before this action.");
return;
}
if (flywayDetails.edition !== "enterprise") {
core.setFailed(
`State-based deployments require Flyway Enterprise edition (current edition: ${flywayDetails.edition}).`,
);
return;
}
const inputs = getInputs();
if (!inputs.targetEnvironment && !inputs.targetUrl) {
core.setFailed(
Expand All @@ -34,20 +40,16 @@ const run = async (): Promise<void> => {

maskSecrets(inputs);

if (flywayDetails.edition === "enterprise") {
if (inputs.skipDriftCheck) {
core.info('Skipping drift check: "skip-drift-check" set to true');
inputs.saveSnapshot = true;
} else {
const { driftDetected, comparisonSupported } = await checkForDrift(inputs);
if (driftDetected) {
core.setFailed("Drift detected. Aborting deployment.");
return;
}
inputs.saveSnapshot = comparisonSupported;
}
if (inputs.skipDriftCheck) {
core.info('Skipping drift check: "skip-drift-check" set to true');
inputs.saveSnapshot = true;
} else {
core.info(`Skipping drift check as edition is not Enterprise (actual edition: ${flywayDetails.edition}).`);
const { driftDetected, comparisonSupported } = await checkForDrift(inputs);
if (driftDetected) {
core.setFailed("Drift detected. Aborting deployment.");
return;
}
inputs.saveSnapshot = comparisonSupported;
}

await deploy(inputs);
Expand Down
38 changes: 13 additions & 25 deletions state/deploy/tests/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,17 @@ describe("run", () => {
expect(setFailed).toHaveBeenCalledWith(expect.stringContaining("Flyway is not installed"));
});

it("should fail when neither url nor environment is provided", async () => {
it("should fail for non-enterprise edition", async () => {
setupFlywayMock({ edition: "Community", deployExitCode: 0 });

await import("../src/main.js");
await vi.dynamicImportSettled();

expect(setFailed).toHaveBeenCalledWith(expect.stringContaining("require Flyway Enterprise edition"));
});

it("should fail when neither url nor environment is provided", async () => {
setupFlywayMock({ edition: "Enterprise", driftExitCode: 0, deployExitCode: 0 });
getInput.mockReturnValue("");

await import("../src/main.js");
Expand Down Expand Up @@ -106,30 +115,8 @@ describe("run", () => {
);
});

it("should not include saveSnapshot for community edition", async () => {
setupFlywayMock({
edition: "Community",
deployExitCode: 0,
});
getInput.mockImplementation((name: string) => {
if (name === "target-url") {
return "jdbc:sqlite:test.db";
}
return "";
});

await import("../src/main.js");
await vi.dynamicImportSettled();

expect(exec).not.toHaveBeenCalledWith(
"flyway",
expect.arrayContaining(["-deploy.saveSnapshot=true"]),
expect.any(Object),
);
});

it("should fail when flyway returns non-zero exit code", async () => {
setupFlywayMock({ edition: "Community", deployExitCode: 1 });
setupFlywayMock({ edition: "Enterprise", driftExitCode: 0, deployExitCode: 1 });
getInput.mockImplementation((name: string) => {
if (name === "target-url") {
return "jdbc:sqlite:test.db";
Expand All @@ -145,7 +132,8 @@ describe("run", () => {

it("should set outputs on successful execution", async () => {
setupFlywayMock({
edition: "Community",
edition: "Enterprise",
driftExitCode: 0,
deployExitCode: 0,
});
getInput.mockImplementation((name: string) => {
Expand Down
7 changes: 5 additions & 2 deletions state/prepare/dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10630,12 +10630,16 @@ await (async () => {
rn("Flyway is not installed or not in PATH. Run red-gate/setup-flyway before this action.");
return;
}
if (e.edition !== "enterprise") {
rn(`State-based deployments require Flyway Enterprise edition (current edition: ${e.edition}).`);
return;
}
let t = Hn();
if (!t.targetEnvironment && !t.targetUrl) {
rn("Either \"target-environment\" or \"target-url\" must be provided for Flyway to connect to a database.");
return;
}
if (Un(t), e.edition === "enterprise") if (t.skipDriftCheck) sn("Skipping drift check: \"skip-drift-check\" set to true");
if (Un(t), t.skipDriftCheck) sn("Skipping drift check: \"skip-drift-check\" set to true");
else {
let { driftDetected: e } = await Wn(t);
if (e) {
Expand All @@ -10646,7 +10650,6 @@ await (async () => {
on("Drift detected. Continuing because fail-on-drift is disabled.");
}
}
else sn(`Skipping drift check as edition is not Enterprise (actual edition: ${e.edition}).`);
await jn(t, e.edition);
let { scriptPath: n } = await Bn(t);
if (!n) {
Expand Down
28 changes: 15 additions & 13 deletions state/prepare/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ const run = async (): Promise<void> => {
core.setFailed("Flyway is not installed or not in PATH. Run red-gate/setup-flyway before this action.");
return;
}
if (flywayDetails.edition !== "enterprise") {
core.setFailed(
`State-based deployments require Flyway Enterprise edition (current edition: ${flywayDetails.edition}).`,
);
return;
}
const inputs = getInputs();
if (!inputs.targetEnvironment && !inputs.targetUrl) {
core.setFailed(
Expand All @@ -36,21 +42,17 @@ const run = async (): Promise<void> => {

maskSecrets(inputs);

if (flywayDetails.edition === "enterprise") {
if (inputs.skipDriftCheck) {
core.info('Skipping drift check: "skip-drift-check" set to true');
} else {
const { driftDetected } = await checkForDrift(inputs);
if (driftDetected) {
if (inputs.failOnDrift) {
core.setFailed("Drift detected. Aborting prepare.");
return;
}
core.warning("Drift detected. Continuing because fail-on-drift is disabled.");
if (inputs.skipDriftCheck) {
core.info('Skipping drift check: "skip-drift-check" set to true');
} else {
const { driftDetected } = await checkForDrift(inputs);
if (driftDetected) {
if (inputs.failOnDrift) {
core.setFailed("Drift detected. Aborting prepare.");
return;
}
core.warning("Drift detected. Continuing because fail-on-drift is disabled.");
}
} else {
core.info(`Skipping drift check as edition is not Enterprise (actual edition: ${flywayDetails.edition}).`);
}

await runCheckChanges(inputs, flywayDetails.edition);
Expand Down
34 changes: 13 additions & 21 deletions state/prepare/tests/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,17 @@ describe("run", () => {
expect(setFailed).toHaveBeenCalledWith(expect.stringContaining("Flyway is not installed"));
});

it("should fail when neither url nor environment is provided", async () => {
it("should fail for non-enterprise edition", async () => {
setupFlywayMock({ edition: "Community", prepareExitCode: 0 });

await import("../src/main.js");
await vi.dynamicImportSettled();

expect(setFailed).toHaveBeenCalledWith(expect.stringContaining("require Flyway Enterprise edition"));
});

it("should fail when neither url nor environment is provided", async () => {
setupFlywayMock({ edition: "Enterprise", driftExitCode: 0, prepareExitCode: 0 });
getInput.mockReturnValue("");

await import("../src/main.js");
Expand Down Expand Up @@ -221,24 +230,6 @@ describe("run", () => {
expect(setFailed).not.toHaveBeenCalled();
});

it("should skip drift check for community edition", async () => {
setupFlywayMock({
edition: "Community",
codeReviewExitCode: 0,
prepareExitCode: 0,
prepareOutput: { scriptFilename: "deployments/D__deployment.sql" },
});
getInput.mockImplementation((name: string) => (name === "target-url" ? "jdbc:sqlite:test.db" : ""));

await import("../src/main.js");
await vi.dynamicImportSettled();

expect(getDriftCheckCalls()).toHaveLength(0);
expect(getPrepareCalls()).toHaveLength(1);
expect(info).toHaveBeenCalledWith(expect.stringContaining("edition is not Enterprise"));
expect(setFailed).not.toHaveBeenCalled();
});

it("should proceed with prepare when no drift detected for enterprise edition", async () => {
setupFlywayMock({
edition: "Enterprise",
Expand Down Expand Up @@ -336,7 +327,8 @@ describe("run", () => {

it("should call runCheckChanges", async () => {
setupFlywayMock({
edition: "Community",
edition: "Enterprise",
driftExitCode: 0,
codeReviewExitCode: 0,
prepareExitCode: 0,
prepareOutput: { scriptFilename: "deployments/D__deployment.sql" },
Expand All @@ -346,7 +338,7 @@ describe("run", () => {
await import("../src/main.js");
await vi.dynamicImportSettled();

expect(runCheckChanges).toHaveBeenCalledWith(expect.any(Object), "community");
expect(runCheckChanges).toHaveBeenCalledWith(expect.any(Object), "enterprise");
});

it("should skip code review when skip-code-review is enabled", async () => {
Expand Down
Loading