Can you also try placing debugging output right before the
"call_command('collectstatic', ...)" command in _build_static_media?Along with this, try printing `command` in pipeline/compilers/less.py (pipeline will be another module in site-packages somewhere, perhaps under a django-pipeline-* directory). Christian On Mon, Jun 12, 2017 at 5:22 PM, Alexander Galperin < [email protected]> wrote: > I've put some print in packaging.py to help debugging. Here's what I have > changed: > def install_pipeline_deps(self, extension, css_bundles, js_bundles): > ... > ... > with open(package_file, 'w') as fp: > fp.write(json.dumps( > { > 'name': '%s-extension' % os.path.basename(os.getcwd()), > 'private': 'true', > 'devDependencies': {}, > 'dependencies': dependencies, > }, > indent=2)) > > old_cwd = os.getcwd() > os.chdir(build_dir) > * print 'PIPELINE_LESS_BINARY = > {}'.format(pipeline_settings.LESS_BINARY)* > * print 'PIPELINE_UGLIFYJS_BINARY = > {}'.format(pipeline_settings.UGLIFYJS_BINARY)* > self.npm_install() > > And the output is: > PIPELINE_LESS_BINARY = /src2/rb-extension-pack/fortinet/build/node_modules > /less/bin/lessc > PIPELINE_UGLIFYJS_BINARY = /src2/rb-extension-pack/fortinet/build/ > node_modules/uglifyjs/bin/uglifyjs > > Also build/node_modules.. created in extention directory, so the path is > correct at this point > > On Monday, June 12, 2017 at 5:17:15 PM UTC-7, Christian Hammond wrote: >> >> Hi Kevin, >> >> printing in settings.py won't tell you anything of value. Those are the >> correct locations at the time that settings.py loaded, but they're >> overridden during the packaging process. The locations mentioned in my >> previous e-mail are where that happens. Solving this will require narrowing >> down the locations where the path is correct and where it's incorrect in >> that process. >> >> Christian >> >> On Mon, Jun 12, 2017 at 2:49 PM, Kevin Yu <[email protected]> wrote: >> >>> Hi Christian, >>> >>> Thanks for trying out. I also did some debugging to see if I can find >>> any information. I added some print in the settings.py >>> >>> PIPELINE_LESS_BINARY = os.path.join(NODE_PATH, 'less', 'bin', 'lessc') >>> PIPELINE_UGLIFYJS_BINARY = os.path.join(NODE_PATH, 'uglifyjs', 'bin', >>> 'uglifyjs') >>> print 'PIPELINE_UGLIFYJS_BINARY = {}'.format(PIPELINE_UGLIFYJS_BINARY) >>> print 'PIPELINE_LESS_BINARY = {}'.format(PIPELINE_LESS_BINARY) >>> >>> >>> >>> And this is what I see in the log: >>> >>> [Mon Jun 12 14:47:50.821618 2017] [:error] [pid 12918:tid >>> 140227234481920] PIPELINE_UGLIFYJS_BINARY = /usr/local/lib/python2.7/dist- >>> packages/ReviewBoard-2.5.12-py2.7.egg/reviewboard/../node_mo >>> dules/uglifyjs/bin/uglifyjs >>> [Mon Jun 12 14:47:50.821692 2017] [:error] [pid 12918:tid >>> 140227234481920] PIPELINE_LESS_BINARY = /usr/local/lib/python2.7/dist- >>> packages/ReviewBoard-2.5.12-py2.7.egg/reviewboard/../node_mo >>> dules/less/bin/lessc >>> >>> >>> >>> On Saturday, June 10, 2017 at 1:43:26 AM UTC-7, Christian Hammond wrote: >>>> >>>> Right. We override this though in djblets/extensions/packaging.py in >>>> install_pipeline_deps(). We compute the path to the extension's >>>> node_modules and its lessc, and we set that in settings. >>>> >>>> I tested locally and it's performing as expected for me. Review Board's >>>> lessc isn't being used, but the extension's is. So something's going wrong >>>> here with the paths. >>>> >>>> How comfortable are you debugging Python? I'm curious as to whether >>>> pipeline_settings.LESS_BINARY in install_pipeline_deps() is being correctly >>>> set. >>>> >>>> Christian >>>> >>>> On Fri, Jun 9, 2017 at 5:51 PM, Kevin Yu <[email protected]> wrote: >>>> >>>>> Looks like the path to the npm_modules are prepopulated based on the >>>>> following code in settings.py: >>>>> # Static media setup >>>>> if RUNNING_TEST: >>>>> PIPELINE_COMPILERS = [] >>>>> else: >>>>> PIPELINE_COMPILERS = [ >>>>> 'djblets.pipeline.compilers.es6.ES6Compiler', >>>>> 'djblets.pipeline.compilers.less.LessCompiler', >>>>> ] >>>>> >>>>> NODE_PATH = os.path.join(REVIEWBOARD_ROOT, '..', 'node_modules') >>>>> >>>>> >>>>> >>>>> On Friday, June 9, 2017 at 5:44:51 PM UTC-7, Kevin Yu wrote: >>>>>> >>>>>> Thanks Christian for the quick reply! much appreciated. >>>>>> >>>>>> It was installed using easy_install under Ubuntu. >>>>>> >>>>>> On Friday, June 9, 2017 at 5:38:11 PM UTC-7, Christian Hammond wrote: >>>>>>> >>>>>>> Hi Kevin, >>>>>>> >>>>>>> I actually don't believe this is related in this case. It looks like >>>>>>> the extension packaging stage is trying to locate the lessc path >>>>>>> relative >>>>>>> to Review Board, which is not correct. It should be locating it from the >>>>>>> extension package. It sets the path prior to building the extension to >>>>>>> the >>>>>>> place in your tree, which, based on that output, should be populated... >>>>>>> >>>>>>> I have to run right now, but let me play around with this when I get >>>>>>> back and see if I can reproduce this. >>>>>>> >>>>>>> In the meantime, how do you install Review Board? Are you using >>>>>>> easy_install or yum? >>>>>>> >>>>>>> Christian >>>>>>> >>>>>>> On Fri, Jun 9, 2017 at 5:34 PM, Kevin Yu <[email protected]> wrote: >>>>>>> >>>>>>>> I just saw on https://www.reviewboard.org >>>>>>>> /docs/manual/dev/extending/extensions/static-files/, it says >>>>>>>> >>>>>>>> Static bundles are packaged along with your extension >>>>>>>> automatically. You don’t have to do anything special. You will, >>>>>>>> however, >>>>>>>> need some node.js <https://nodejs.org/> dependencies in order to >>>>>>>> package static media bundles. >>>>>>>> >>>>>>>> *If you’re running Review Board 2.5.7+, these dependencies will be >>>>>>>> installed for you when you begin to build the package.* >>>>>>>> >>>>>>>> *If you’re running an older version, you will need to manually >>>>>>>> install them yourself. First, make sure you have a modern version of >>>>>>>> node.js installed and then run:* >>>>>>>> >>>>>>>> $ sudo npm install -g less uglifyjs >>>>>>>> >>>>>>>> I am wondering if this is related... >>>>>>>> >>>>>>>> On Friday, June 9, 2017 at 4:41:10 PM UTC-7, Kevin Yu wrote: >>>>>>>>> >>>>>>>>> On our server, we had reviewboard core 2.5.6.1 running with our >>>>>>>>> own extension. it was all fine until we recently upgraded reviewboard >>>>>>>>> core >>>>>>>>> to 2.5.12. After the upgrade, we can't run python setup.py -v build >>>>>>>>> anymore... The error is as follows: >>>>>>>>> devops@Reviewboard-Test-trunk:/tmp/ReviewBoardExt$ python >>>>>>>>> setup.py -v build >>>>>>>>> running build >>>>>>>>> running build_py >>>>>>>>> running build_static_files >>>>>>>>> Installing node packages... >>>>>>>>> npm http GET https://registry.npmjs.org/uglifyjs/2.4.10 >>>>>>>>> npm http GET https://registry.npmjs.org/less/2.7.1 >>>>>>>>> npm http 304 https://registry.npmjs.org/less/2.7.1 >>>>>>>>> npm http 304 https://registry.npmjs.org/uglifyjs/2.4.10 >>>>>>>>> npm WARN deprecated [email protected]: uglifyjs is deprecated - use >>>>>>>>> uglify-js instead. >>>>>>>>> npm WARN engine [email protected]: wanted: {"node":">=0.12"} (current: >>>>>>>>> {"node":"v0.10.25","npm":"1.3.10"}) >>>>>>>>> npm http GET https://registry.npmjs.org/source-map/0.1.34 >>>>>>>>> npm http GET https://registry.npmjs.org/yargs >>>>>>>>> npm http GET https://registry.npmjs.org/async >>>>>>>>> npm http GET https://registry.npmjs.org/uglify-to-browserify >>>>>>>>> npm http 304 https://registry.npmjs.org/source-map/0.1.34 >>>>>>>>> npm http 304 https://registry.npmjs.org/yargs >>>>>>>>> npm http 304 https://registry.npmjs.org/async >>>>>>>>> npm http 304 https://registry.npmjs.org/uglify-to-browserify >>>>>>>>> npm http GET https://registry.npmjs.org/amdefine >>>>>>>>> npm http 304 https://registry.npmjs.org/amdefine >>>>>>>>> npm http GET https://registry.npmjs.org/errno >>>>>>>>> npm http GET https://registry.npmjs.org/graceful-fs >>>>>>>>> npm http GET https://registry.npmjs.org/image-size >>>>>>>>> npm http GET https://registry.npmjs.org/mime >>>>>>>>> npm http GET https://registry.npmjs.org/mkdirp >>>>>>>>> npm http GET https://registry.npmjs.org/promise >>>>>>>>> npm http GET https://registry.npmjs.org/source-map >>>>>>>>> npm http 304 https://registry.npmjs.org/errno >>>>>>>>> npm http 304 https://registry.npmjs.org/graceful-fs >>>>>>>>> npm http 304 https://registry.npmjs.org/image-size >>>>>>>>> npm http 304 https://registry.npmjs.org/mime >>>>>>>>> npm http 304 https://registry.npmjs.org/promise >>>>>>>>> npm http 304 https://registry.npmjs.org/source-map >>>>>>>>> npm http 304 https://registry.npmjs.org/mkdirp >>>>>>>>> npm http GET https://registry.npmjs.org/prr >>>>>>>>> npm http 304 https://registry.npmjs.org/prr >>>>>>>>> npm http GET https://registry.npmjs.org/minimist/0.0.8 >>>>>>>>> npm http 304 https://registry.npmjs.org/minimist/0.0.8 >>>>>>>>> npm http GET https://registry.npmjs.org/asap >>>>>>>>> npm http 304 https://registry.npmjs.org/asap >>>>>>>>> [email protected] node_modules/uglifyjs >>>>>>>>> ├── [email protected] >>>>>>>>> ├── [email protected] >>>>>>>>> ├── [email protected] >>>>>>>>> └── [email protected] ([email protected]) >>>>>>>>> >>>>>>>>> [email protected] node_modules/less >>>>>>>>> ├── [email protected] >>>>>>>>> ├── [email protected] >>>>>>>>> ├── [email protected] >>>>>>>>> ├── [email protected] ([email protected]) >>>>>>>>> ├── [email protected] ([email protected]) >>>>>>>>> ├── [email protected] ([email protected]) >>>>>>>>> └── [email protected] >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/css/rev_req_det.less' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/ >>>>>>>>> static/js/views/account_handler.js' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/ >>>>>>>>> static/js/views/branch_builds.js' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/ >>>>>>>>> static/js/views/bootstrap.js' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/ >>>>>>>>> static/js/views/apprreqView.js' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/ >>>>>>>>> static/js/views/test_cvrg_rprt.js' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/ >>>>>>>>> static/js/views/ftnchkHoldItView.js' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/ >>>>>>>>> static/js/views/sel_rqst_4_det_copy.js' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/ >>>>>>>>> static/js/views/approval_status_View.js' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/ >>>>>>>>> static/js/views/dashboard.js' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/ >>>>>>>>> static/js/views/rqst_descr.js' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/ >>>>>>>>> static/js/views/cm_portalView.js' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/Remove.png' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/fortinet.png' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/ >>>>>>>>> static/images/[email protected]' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/[email protected]' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/teamlead.png' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/ >>>>>>>>> static/images/favicon_notify.png' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/Create.png' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/ftnt.ico' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/[email protected]' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/ >>>>>>>>> static/images/shipit-grey.png' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/ >>>>>>>>> static/images/[email protected]' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/Up.png' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/Bottom.png' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/[email protected]' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/stop16.png' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/[email protected]' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/[email protected]' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/shipit.png' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/[email protected]' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/[email protected]' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/static/images/Down.png' >>>>>>>>> Copying '/tmp/ReviewBoardExt/fortinet/ >>>>>>>>> static/images/[email protected]' >>>>>>>>> Traceback (most recent call last): >>>>>>>>> File "setup.py", line 27, in <module> >>>>>>>>> 'evolutions/*.*', >>>>>>>>> File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.5.12- >>>>>>>>> py2.7.egg/reviewboard/extensions/packaging.py", line 48, in setup >>>>>>>>> setuptools_setup(**setup_kwargs) >>>>>>>>> File "/usr/lib/python2.7/distutils/core.py", line 151, in setup >>>>>>>>> dist.run_commands() >>>>>>>>> File "/usr/lib/python2.7/distutils/dist.py", line 953, in >>>>>>>>> run_commands >>>>>>>>> self.run_command(cmd) >>>>>>>>> File "/usr/lib/python2.7/distutils/dist.py", line 972, in >>>>>>>>> run_command >>>>>>>>> cmd_obj.run() >>>>>>>>> File "/usr/lib/python2.7/distutils/command/build.py", line 128, >>>>>>>>> in run >>>>>>>>> self.run_command(cmd_name) >>>>>>>>> File "/usr/lib/python2.7/distutils/cmd.py", line 326, in >>>>>>>>> run_command >>>>>>>>> self.distribution.run_command(command) >>>>>>>>> File "/usr/lib/python2.7/distutils/dist.py", line 972, in >>>>>>>>> run_command >>>>>>>>> cmd_obj.run() >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/Djblets-0.9.7-py2.7.egg/djblets/extensions/packaging.py", >>>>>>>>> line 422, in run >>>>>>>>> self.run_command('build_static_files') >>>>>>>>> File "/usr/lib/python2.7/distutils/cmd.py", line 326, in >>>>>>>>> run_command >>>>>>>>> self.distribution.run_command(command) >>>>>>>>> File "/usr/lib/python2.7/distutils/dist.py", line 972, in >>>>>>>>> run_command >>>>>>>>> cmd_obj.run() >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/Djblets-0.9.7-py2.7.egg/djblets/extensions/packaging.py", >>>>>>>>> line 290, in run >>>>>>>>> self._build_static_media(extension) >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/Djblets-0.9.7-py2.7.egg/djblets/extensions/packaging.py", >>>>>>>>> line 360, in _build_static_media >>>>>>>>> call_command('collectstatic', interactive=False, verbosity=2) >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/Django-1.6.11-py2.7.egg/django/core/management/__init__.py", >>>>>>>>> line 159, in call_command >>>>>>>>> return klass.execute(*args, **defaults) >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/Django-1.6.11-py2.7.egg/django/core/management/base.py", >>>>>>>>> line 285, in execute >>>>>>>>> output = self.handle(*args, **options) >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/Django-1.6.11-py2.7.egg/django/core/management/base.py", >>>>>>>>> line 415, in handle >>>>>>>>> return self.handle_noargs(**options) >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/Django-1.6.11-py2.7.egg/django/contrib/staticfiles >>>>>>>>> /management/commands/collectstatic.py", line 173, in handle_noargs >>>>>>>>> collected = self.collect() >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/Django-1.6.11-py2.7.egg/django/contrib/staticfiles >>>>>>>>> /management/commands/collectstatic.py", line 119, in collect >>>>>>>>> for original_path, processed_path, processed in processor: >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/django_pipeline-1.3.27-py2.7.egg/pipeline/storage.py", >>>>>>>>> line 32, in post_process >>>>>>>>> packager.pack_stylesheets(package) >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/django_pipeline-1.3.27-py2.7.egg/pipeline/packager.py", >>>>>>>>> line 94, in pack_stylesheets >>>>>>>>> variant=package.variant, **kwargs) >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/django_pipeline-1.3.27-py2.7.egg/pipeline/packager.py", >>>>>>>>> line 103, in pack >>>>>>>>> paths = self.compile(package.paths, force=True) >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/django_pipeline-1.3.27-py2.7.egg/pipeline/packager.py", >>>>>>>>> line 97, in compile >>>>>>>>> return self.compiler.compile(paths, force=force) >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/django_pipeline-1.3.27-py2.7.egg/pipeline/compilers/__init__.py", >>>>>>>>> line 55, in compile >>>>>>>>> return list(executor.map(_compile, paths)) >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/futures-3.0.5-py2.7.egg/concurrent/futures/_base.py", >>>>>>>>> line 581, in result_iterator >>>>>>>>> yield future.result() >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/futures-3.0.5-py2.7.egg/concurrent/futures/_base.py", >>>>>>>>> line 405, in result >>>>>>>>> return self.__get_result() >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/futures-3.0.5-py2.7.egg/concurrent/futures/thread.py", >>>>>>>>> line 55, in run >>>>>>>>> result = self.fn(*self.args, **self.kwargs) >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/django_pipeline-1.3.27-py2.7.egg/pipeline/compilers/__init__.py", >>>>>>>>> line 40, in _compile >>>>>>>>> outdated=outdated, force=force) >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/django_pipeline-1.3.27-py2.7.egg/pipeline/compilers/less.py", >>>>>>>>> line 22, in compile_file >>>>>>>>> return self.execute_command(command, cwd=dirname(infile)) >>>>>>>>> File "/usr/local/lib/python2.7/dist >>>>>>>>> -packages/django_pipeline-1.3.27-py2.7.egg/pipeline/compilers/__init__.py", >>>>>>>>> line 99, in execute_command >>>>>>>>> raise CompilerError(stderr) >>>>>>>>> pipeline.exceptions.CompilerError: /bin/sh: 1: >>>>>>>>> /usr/local/lib/python2.7/dist-packages/ReviewBoard-2.5.12-py >>>>>>>>> 2.7.egg/reviewboard/../node_modules/less/bin/lessc: not found >>>>>>>>> >>>>>>>>> The path it tries to find lessc seems wrong as well. the lessc >>>>>>>>> should be in /usr/local/bin/lessc. >>>>>>>>> >>>>>>>>> Has anyone run into the same issue? >>>>>>>>> >>>>>>>> -- >>>>>>>> Supercharge your Review Board with Power Pack: >>>>>>>> https://www.reviewboard.org/powerpack/ >>>>>>>> Want us to host Review Board for you? Check out RBCommons: >>>>>>>> https://rbcommons.com/ >>>>>>>> Happy user? Let us know! https://www.reviewboard.org/users/ >>>>>>>> --- >>>>>>>> You received this message because you are subscribed to the Google >>>>>>>> Groups "reviewboard" group. >>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>> send an email to [email protected]. >>>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Christian Hammond >>>>>>> President/CEO of Beanbag <https://www.beanbaginc.com/> >>>>>>> Makers of Review Board <https://www.reviewboard.org/> >>>>>>> >>>>>> -- >>>>> Supercharge your Review Board with Power Pack: >>>>> https://www.reviewboard.org/powerpack/ >>>>> Want us to host Review Board for you? Check out RBCommons: >>>>> https://rbcommons.com/ >>>>> Happy user? Let us know! https://www.reviewboard.org/users/ >>>>> --- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "reviewboard" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>> an email to [email protected]. >>>>> For more options, visit https://groups.google.com/d/optout. >>>>> >>>> >>>> >>>> >>>> -- >>>> Christian Hammond >>>> President/CEO of Beanbag <https://www.beanbaginc.com/> >>>> Makers of Review Board <https://www.reviewboard.org/> >>>> >>> -- >>> Supercharge your Review Board with Power Pack: >>> https://www.reviewboard.org/powerpack/ >>> Want us to host Review Board for you? Check out RBCommons: >>> https://rbcommons.com/ >>> Happy user? Let us know! https://www.reviewboard.org/users/ >>> --- >>> You received this message because you are subscribed to the Google >>> Groups "reviewboard" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to [email protected]. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> >> >> -- >> Christian Hammond >> President/CEO of Beanbag <https://www.beanbaginc.com/> >> Makers of Review Board <https://www.reviewboard.org/> >> > -- > Supercharge your Review Board with Power Pack: > https://www.reviewboard.org/powerpack/ > Want us to host Review Board for you? Check out RBCommons: > https://rbcommons.com/ > Happy user? Let us know! https://www.reviewboard.org/users/ > --- > You received this message because you are subscribed to the Google Groups > "reviewboard" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- Christian Hammond President/CEO of Beanbag <https://www.beanbaginc.com/> Makers of Review Board <https://www.reviewboard.org/> -- Supercharge your Review Board with Power Pack: https://www.reviewboard.org/powerpack/ Want us to host Review Board for you? Check out RBCommons: https://rbcommons.com/ Happy user? Let us know! https://www.reviewboard.org/users/ --- You received this message because you are subscribed to the Google Groups "reviewboard" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
