Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release/integration/azdevops/v1.0.8 #663

Merged
merged 5 commits into from
Sep 20, 2024
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
34 changes: 25 additions & 9 deletions .github/workflows/publish.azurepipelineextension.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
name: Publish to Azure Pipeline Extension
on:
workflow_dispatch:
inputs:
dry_run:
description: 'Run without publishing'
required: true
default: 'false'
type: boolean

jobs:
publish-az-pipeline-ext:
Expand All @@ -15,6 +21,15 @@ jobs:
- name: Get the source code
uses: actions/checkout@v3

# - name: Set up Docker
# uses: docker/setup-buildx-action@v3
#
# - name: Run tests in Docker
# run: |
# cd ksm-azure-devops-secrets-task
# docker build -t keeper-secrets-test .
# docker run --rm keeper-secrets-test ./tests/run-tests.sh

- name: Retrieve secrets from KSM
id: ksmsecrets
uses: Keeper-Security/ksm-action@master
Expand All @@ -24,23 +39,24 @@ jobs:
DJz3ilHBHIbIZqkTClDV5Q/field/password > PAT

- name: Build
if: success()
run: |
cd ksm-azure-devops-secrets-task
npm install
npm run build


- name: Publish
if: success() && github.event.inputs.dry_run == 'false'
run: |
npm install -g tfx-cli
tfx extension publish --token ${{ steps.ksmsecrets.outputs.PAT }}
ls -lh *.vsix

- name: Step To run on failure
if: ${{ failure() }}
run: |
curl --request POST \
--url https://api.github.com/repos/${{ github.repository }}/issues \
--header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
--header 'content-type: application/json' \
--data '{"title": "Issue created due to fialure in workflow ${{ github.workflow }}, run #: ${{ github.run_id }}","body": "This issue was automatically created by the GitHub Action workflow **${{ github.workflow }}**.\n\nDue to failure in run: [${{ github.run_id }}](https://github.com/Keeper-Security/secrets-manager/actions/runs/${{ github.run_id }}).\n\nIf error is related to access denied (expiration of Personal Access Token, aka PAT), here are the steps to generate a new one:\n\n-Steps to generate one documented [HERE](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=preview-page)\n- Update \"Password\" field in record UID `DJz3ilHBHIbIZqkTClDV5Q` (located in shared folder named \"Secrets Manager\")"}'
# - name: Step To run on failure
# if: ${{ failure() }}
# run: |
# curl --request POST \
# --url https://api.github.com/repos/${{ github.repository }}/issues \
# --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
# --header 'content-type: application/json' \
# --data '{"title": "Issue created due to failure in workflow ${{ github.workflow }}, run #: ${{ github.run_id }}","body": "This issue was automatically created by the GitHub Action workflow **${{ github.workflow }}**.\n\nDue to failure in run: [${{ github.run_id }}](https://github.com/Keeper-Security/secrets-manager/actions/runs/${{ github.run_id }}).\n\nIf error is related to access denied (expiration of Personal Access Token, aka PAT), here are the steps to generate a new one:\n\n-Steps to generate one documented [HERE](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=preview-page)\n- Update \"Password\" field in record UID `DJz3ilHBHIbIZqkTClDV5Q` (located in shared folder named \"Secrets Manager\")"}'
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
npm-debug.log
.env
*.vsix
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM node:10

WORKDIR /app

# Copy package files
COPY package*.json ./

# Install dependencies and TypeScript globally
RUN npm install && npm install -g typescript mocha dotenv core-js

# Copy the entire project
COPY . .

# Set the entry point to the run-tests.sh script in the tests directory
ENTRYPOINT ["./tests/run-tests.sh"]
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,49 @@ import {
} from "@keeper-security/secrets-manager-core"
import * as fs from "fs"

/**
* Polyfill for Array.prototype.at() method
*
* Why this is needed:
* 1. The Array.prototype.at() method was introduced in ES2022 but is not available in all JavaScript environments.
* 2. Specifically, as of September 2024, Azure Pipelines' default Node.js version does not support this method.
* 3. It provides a convenient way to access array elements, especially with negative indices (e.g., arr.at(-1) for the last element).
* 4. This polyfill ensures consistent behavior across different environments, including Azure Pipelines.
*
* How it works:
* 1. We first declare the 'at' method in the global Array interface for TypeScript type safety.
* 2. We then check if the method already exists to avoid overwriting native implementations.
* 3. If not present, we implement the method, handling both positive and negative indices.
*
* Note: This polyfill should be reviewed periodically and removed once Azure Pipelines updates its
* default Node.js version to one that includes native support for Array.prototype.at() (Node.js 16.6.0 and later).
* Keep an eye on Azure Pipelines documentation for updates on supported Node.js versions.
*/

// Declare the 'at' method in the global Array interface for TypeScript
declare global {
interface Array<T> {
at(index: number): T | undefined;
}
}

// Only add the polyfill if the method doesn't already exist
if (!Array.prototype.at) {
tl.debug("Array.prototype.at() is not supported in this environment. Adding polyfill.");
Array.prototype.at = function<T>(this: T[], index: number): T | undefined {
// Convert the index to an integer
const n = Math.trunc(index) || 0;

// Handle negative indices by counting from the end of the array
if (n < 0) return this[this.length + n];

// Return the element at the calculated index
return this[n];
};
} else {
tl.debug("Array.prototype.at() is natively supported in this environment.");
}

/*
Azure Pipeline:
- Pipeline Variable: variable that can be referenced in other places inside the pipeline.
Expand All @@ -23,7 +66,7 @@ import * as fs from "fs"
Unlike a general pipeline variable, an output variable is defined and value
generated by the output of a task. Output variables are dynamic and represent
the result of a particular task. They are not statically defined as above.
You will never know an output variables value until a task in the pipeline
You will never know an output variable's value until a task in the pipeline
runs.

*/
Expand Down Expand Up @@ -125,7 +168,7 @@ async function run() {
})
// there's a slight chance a valid title to match a recordUID (22 url-safe base64 chars)
// or a missing record or record not shared to the KSM App - we need to pull all records
if (uids_to_retrieve && (!secrets || secrets.records.length < uids_to_retrieve.length)) {
if (uids_to_retrieve.length > 0 && (!secrets || secrets.records.length < uids_to_retrieve.length)) {
tl.debug("KSM didn't get expected number of records - requesting all (search by title or missing UID /not shared to the app/)")
uids_to_retrieve = []
secrets = await getSecrets({storage: loadJsonConfig(config)}, uids_to_retrieve).
Expand Down
Loading
Loading