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

Uploading source maps to sentry when using serverless-plugin-typescript #81

Open
Imran99 opened this issue Mar 30, 2023 · 1 comment
Open

Comments

@Imran99
Copy link

Imran99 commented Mar 30, 2023

Hi,

Just wondering if anyone has managed to get source map uploads to sentry working when using ts, and serverless-plugin-typescript to build and deploy ts lambdas. Serverless plugin typescript temporarily creates its outputs in a .build directory but I think this may be deleted after the packaing phase completes in sls and before the sentry plugin runs.

@fridaystreet
Copy link

fridaystreet commented Dec 11, 2024

COuldn't get the plugin to do it either. We just do it via the esbuild plugin

const getSentryPlugin = async (log) => {
  if (process.env.NODE_ENV === 'development') {
    return { name: 'nosentry', setup: () => log('skip sentry plugin' ) }
  }
  const release = await gitRelease(process.env.NODE_ENV)
  return sentryEsbuildPlugin({
    authToken: process.env.SENTRY_AUTH_TOKEN,
    org: "myorg",
    project: "myproject",
    telemetry: true,
    environment: process.env.NODE_ENV,
    release
  })
}

gitRelease.js

const  { exec } = require('child_process')

class GitRev {
  opts

  constructor(opts) {
    this.opts = opts ?? { cwd: __dirname };
  }

  async _command(cmd) {
    return new Promise((resolve, reject) => {
      exec(cmd, this.opts, function (err, stdout /*, stderr */) {
        return err ? reject(err) : resolve(stdout.replace(/\n/g, "").trim());
      });
    });
  }

  async short() {
    return this._command("git rev-parse --short HEAD");
  }

  async long() {
    return this._command("git rev-parse HEAD");
  }

  async branch() {
    return this._command("git rev-parse --abbrev-ref HEAD");
  }

  async tag() {
    return this._command("git describe --always --tag --abbrev=0");
  }

  async log() {
    let str = await this._command(
      'git log --no-color --pretty=format:\'[ "%H", "%s", "%cr", "%an" ],\' --abbrev-commit',
    );
    str = str.substr(0, str.length - 1);
    return JSON.parse("[" + str + "]");
  }

  async exactTag() {
    // Suppress errors as this will fail if no tag exists yet
    return this._command("git describe --exact-match --tags HEAD").catch(() => undefined);
  }

  async origin() {
    return this._command("git config --get remote.origin.url");
  }
}

const resolveGitRefs = async (gitRev, release) => {
  const origin = await gitRev.origin();
  const commit = await gitRev.long();
  let repository = /[:/]([^/]+\/[^/]+?)(?:\.git)?$/i.exec(origin)?.[1];
  if (repository && origin.includes("gitlab")) {
    // GitLab uses spaces around the slashes in the repository name
    repository = repository.replace(/\//g, " / ");
  }

  if (Array.isArray(release.refs)) {
    const refs = release.refs;
    refs.forEach((ref) => {
      if (ref && ref.repository === "git") {
        ref.repository = repository ?? "";
      }
      if (ref && ref.commit === "git") {
        ref.commit = commit;
      }
      if (ref && ref.previousCommit === "git") {
        delete ref.previousCommit; // not available via git
      }
    });
    return { ...release, refs }
  }
}

module.exports=async (env) => {
  try {
    const gitRev = new GitRev()
    let release = {
      version: (await gitRev.exactTag()) ?? (await gitRev.short()),
      refs: [{
        repository: "git",
        commit: "git",
      }]
    }

    return await resolveGitRefs(gitRev, release);
  } catch (err) {
    throw new Error(`Sentry: No Git available - ${err.message}`);
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants