@mikarinneoracle/oci-cdk-code-only-preview 0.0.25 → 0.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -142,6 +142,16 @@ entrypoint: node func.js
142
142
 
143
143
  Keep `@fnproject/fdk` in `package.json` dependencies. The function source file uses `fdk.handle(...)`; it is not the OCI handler value.
144
144
 
145
+ For Java, the code-only archive must contain exactly one fat/uber JAR at the ZIP root. Build it first and point OCDK to it when necessary:
146
+
147
+ ```bash
148
+ export OCI_CODE_ONLY_RUNTIME_NAME='java21.ol9'
149
+ export OCI_FUNCTION_HANDLER='com.example.fn.HelloFunction::handleRequest'
150
+ export OCI_FUNCTION_JAR_PATH='target/my-function.jar'
151
+ ```
152
+
153
+ If exactly one non-source JAR exists in the project root or `target/`, `OCI_FUNCTION_JAR_PATH` is optional. Java archives do not contain the project source tree or a `function/` directory.
154
+
145
155
  #### Find the available code-only runtimes
146
156
 
147
157
  The exact `OCI_CODE_ONLY_RUNTIME_NAME` values are enabled per tenancy and region during this Limited Availability preview. Query the Preview CLI instead of copying a runtime name from another environment:
@@ -167,7 +177,7 @@ export OCI_FUNCTION_APP_NAME='my-existing-function-app'
167
177
 
168
178
  These settings are optional: `OCI_CODE_ONLY_SOURCE_DIR` (defaults to the current directory), `OCI_FUNCTION_MEMORY_MB` (from `func.yaml`, otherwise `256`), and `OCI_FUNCTION_TIMEOUT_SECONDS` (from `func.yaml`, otherwise `30`). `OCI_TENANCY_ID`, `OCI_REGION`, and `OCI_NAMESPACE` are also optional when they can be resolved from the active OCI CLI profile.
169
179
 
170
- Each deploy re-builds `<function-name>.zip` in the project root and uploads that file. The ZIP has the required `function/` directory at its root, includes source files, and excludes `node_modules`, `package-lock.json`, `.git`, `.tools`, `.terraform`, `cdktf.out`, and the generated `tail-function-logs.js`. For Node.js functions, `package.json` remains in the archive so OCI can install the FDK and other dependencies, but OCDK removes its own package dependency (`@mikarinneoracle/oci-cdk-code-only-preview`, and the legacy package name) from the copied manifest. A successful code-only destroy removes this ZIP after Terraform has destroyed the Function App and infrastructure. With the default `OCI_STACK_ACTION=full-stack`, OCDK creates the API Gateway and uses a Terraform data source to resolve the CLI-managed function OCID for its route. The first code-only deploy therefore runs Terraform once to create the Function App, uploads the function, then runs Terraform again to create the Gateway deployment. Set `OCI_STACK_ACTION=function-only` to omit API Gateway.
180
+ Each deploy re-builds `<function-name>.zip` in the project root and uploads that file. The ZIP has the required `function/` directory at its root, includes source files, and excludes `node_modules`, `package-lock.json`, `.git`, `.tools`, `.terraform`, `cdktf.out`, and the generated `tail-function-logs.js`. For Node.js functions, a sanitized `package.json` remains so OCI can install the FDK and other dependencies; OCDK removes its own package dependency (`@mikarinneoracle/oci-cdk-code-only-preview`, and the legacy package name) from that copied manifest. For Python and Java code-only functions, `package.json` is excluded entirely. A successful code-only destroy removes this ZIP after Terraform has destroyed the Function App and infrastructure. With the default `OCI_STACK_ACTION=full-stack`, OCDK creates the API Gateway and uses a Terraform data source to resolve the CLI-managed function OCID for its route. The first code-only deploy therefore runs Terraform once to create the Function App, uploads the function, then runs Terraform again to create the Gateway deployment. Set `OCI_STACK_ACTION=function-only` to omit API Gateway.
171
181
 
172
182
  After a successful code-only deploy, OCDK writes the log IDs for `npx ocdk tail:execution-log` automatically.
173
183
 
@@ -94,15 +94,53 @@ function preparePackageManifest(archiveRoot) {
94
94
  }
95
95
  }
96
96
 
97
- function createArchive(functionName) {
97
+ function resolveJavaJar() {
98
+ const configuredPath = (process.env.OCI_CODE_ONLY_JAR_PATH || process.env.OCI_FUNCTION_JAR_PATH || '').trim();
99
+ if (configuredPath) {
100
+ const jarPath = path.resolve(projectDir, configuredPath);
101
+ if (!fs.existsSync(jarPath) || !fs.statSync(jarPath).isFile() || !jarPath.endsWith('.jar')) {
102
+ fail(`OCI_FUNCTION_JAR_PATH must point to an existing .jar file: ${jarPath}`);
103
+ }
104
+ return jarPath;
105
+ }
106
+ const candidates = [projectDir, path.join(projectDir, 'target')]
107
+ .flatMap((directory) => {
108
+ if (!fs.existsSync(directory)) return [];
109
+ return fs.readdirSync(directory)
110
+ .filter((name) => name.endsWith('.jar') && !name.endsWith('-sources.jar') && !name.endsWith('-javadoc.jar') && !name.startsWith('original-'))
111
+ .map((name) => path.join(directory, name));
112
+ });
113
+ const uniqueCandidates = [...new Set(candidates)];
114
+ if (uniqueCandidates.length === 1) return uniqueCandidates[0];
115
+ const found = uniqueCandidates.length ? ` Found: ${uniqueCandidates.join(', ')}` : '';
116
+ fail(`Java code-only deploy requires exactly one fat/uber JAR. Build the function first, or set OCI_FUNCTION_JAR_PATH to the JAR file.${found}`);
117
+ }
118
+
119
+ function createArchive(functionName, runtimeName) {
98
120
  if (!fs.existsSync(projectDir) || !fs.statSync(projectDir).isDirectory()) {
99
121
  fail(`source directory does not exist: ${projectDir}`);
100
122
  }
101
123
  const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ocdk-code-only-'));
102
124
  const archiveFileName = codeOnlyArchiveFileName(functionName);
103
125
  const archivePath = path.join(projectDir, archiveFileName);
126
+ const isJavaRuntime = runtimeName.toLowerCase().startsWith('java');
127
+ const isNodeRuntime = runtimeName.toLowerCase().startsWith('node');
128
+ if (isJavaRuntime) {
129
+ const jarPath = resolveJavaJar();
130
+ const jarName = path.basename(jarPath);
131
+ fs.copyFileSync(jarPath, path.join(tempDir, jarName));
132
+ fs.rmSync(archivePath, { force: true });
133
+ const zip = spawnSync('zip', ['-q', '-r', archivePath, jarName], { cwd: tempDir, encoding: 'utf8', shell: false });
134
+ if (zip.error || zip.status !== 0) {
135
+ fs.rmSync(tempDir, { recursive: true, force: true });
136
+ fs.rmSync(archivePath, { force: true });
137
+ fail(`could not create Java archive with zip: ${zip.stderr?.trim() || zip.error?.message || 'unknown error'}`);
138
+ }
139
+ return { tempDir, archivePath };
140
+ }
104
141
  const archiveRoot = path.join(tempDir, 'function');
105
142
  const excludedTopLevel = new Set(['node_modules', '.git', '.tools', '.terraform', 'cdktf.out', 'tail-function-logs.js', 'package-lock.json']);
143
+ if (!isNodeRuntime) excludedTopLevel.add('package.json');
106
144
  fs.cpSync(projectDir, archiveRoot, {
107
145
  recursive: true,
108
146
  filter: (sourcePath) => {
@@ -112,7 +150,7 @@ function createArchive(functionName) {
112
150
  return !excludedTopLevel.has(relativePath.split(path.sep)[0]);
113
151
  },
114
152
  });
115
- preparePackageManifest(archiveRoot);
153
+ if (isNodeRuntime) preparePackageManifest(archiveRoot);
116
154
  fs.rmSync(archivePath, { force: true });
117
155
  const zip = spawnSync('zip', ['-q', '-r', archivePath, 'function'], { cwd: tempDir, encoding: 'utf8', shell: false });
118
156
  if (zip.error || zip.status !== 0) {
@@ -165,7 +203,7 @@ function main() {
165
203
  const metadata = readFunctionMetadata();
166
204
  const applicationId = (process.env.OCI_FUNCTION_APP_ID || '').trim();
167
205
  if (!applicationId) fail('Terraform output OCI_FUNCTION_APP_ID is missing. Run through "ocdk deploy --code-only".');
168
- const archive = createArchive(metadata.functionName);
206
+ const archive = createArchive(metadata.functionName, metadata.runtimeName);
169
207
  try {
170
208
  const functionId = findFunctionId(applicationId, metadata.functionName);
171
209
  const commonArgs = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikarinneoracle/oci-cdk-code-only-preview",
3
- "version": "0.0.25",
3
+ "version": "0.0.27",
4
4
  "description": "OCI CDK stack for OCI Functions, API Gateway, and related infrastructure",
5
5
  "main": "lib/index.js",
6
6
  "bin": {