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.

Reply via email to