Skip to content

Commit

Permalink
Fix failure to touch /opt/ros/$DISTRO/setup.sh due to insufficient pe…
Browse files Browse the repository at this point in the history
…rmissions (#303)

* Add a test that should fail due to insufficient permissions to touch /opt/ros/foxy
* Don't source ros setup.sh if it doesn't exist, rather than creating it to blindly source

Signed-off-by: Emerson Knapp <emerson.b.knapp@gmail.com>
  • Loading branch information
emersonknapp authored Aug 13, 2020
1 parent 422ec16 commit 875dfcc
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

repositories:
rmw:
type: git
url: https://github.com/ros2/rmw.git
version: foxy
17 changes: 16 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,21 @@ jobs:
# TODO(tmoulard): re-enable this test once it passes on Windows
if: matrix.os != 'windows-latest'

test_ros2_foxy_package_with_dependencies:
name: "Test ROS2 foxy package with ROS dependencies"
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: ros-tooling/setup-ros@0.0.25
with:
required-ros-distributions: foxy
- uses: ./
with:
package-name: rmw
target-ros2-distro: foxy
vcs-repo-file-url: "${{ github.workspace }}/.github/workflows/repo_file_for_test_cpp_with_dependency.repos"


test_ros2_docker:
name: "Test ROS 2 package"
runs-on: ubuntu-latest
Expand Down Expand Up @@ -390,7 +405,7 @@ jobs:
# serves two purposes:
# - Don't skip this job if dependent jobs have failed.
# - On a fork, we don't have the secrets to authenticate to AWS.
if: ${{ ! github.event.repository.fork && ! github.event.pull_request.head.repo.fork }}
if: ${{ !github.event.repository.fork && !github.event.pull_request.head.repo.fork }}
steps:
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
Expand Down
56 changes: 31 additions & 25 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3337,20 +3337,10 @@ function run() {
if (!validateDistros(targetRos1Distro, targetRos2Distro)) {
return;
}
// Source any installed ROS binary distribution, safely creating an empty setup file if it is not present
let commandPrefix = "";
if (isLinux) {
if (targetRos1Distro) {
commandPrefix += `mkdir -p /opt/ros/${targetRos1Distro} && touch /opt/ros/${targetRos1Distro}/setup.sh && source /opt/ros/${targetRos1Distro}/setup.sh && `;
}
if (targetRos2Distro) {
commandPrefix += `mkdir -p /opt/ros/${targetRos2Distro} && touch /opt/ros/${targetRos2Distro}/setup.sh && source /opt/ros/${targetRos2Distro}/setup.sh && `;
}
}
// rosdep on Windows does not reliably work on Windows, see
// rosdep does not reliably work on Windows, see
// ros-infrastructure/rosdep#610 for instance. So, we do not run it.
if (!isWindows) {
yield execBashCommand("rosdep update", commandPrefix);
yield execBashCommand("rosdep update");
}
// Reset colcon configuration.
yield io.rmRF(path.join(os.homedir(), ".colcon"));
Expand All @@ -3364,7 +3354,7 @@ function run() {
};
const curlFlags = curlFlagsArray.join(" ");
for (let vcsRepoFileUrl of vcsRepoFileUrlListResolved) {
yield execBashCommand(`curl ${curlFlags} '${vcsRepoFileUrl}' | vcs import --force --recursive src/`, commandPrefix, options);
yield execBashCommand(`curl ${curlFlags} '${vcsRepoFileUrl}' | vcs import --force --recursive src/`, undefined, options);
}
// If the package under tests is part of ros.repos, remove it first.
// We do not want to allow the "default" head state of the package to
Expand All @@ -3373,7 +3363,7 @@ function run() {
const posixRosWorkspaceDir = isWindows
? rosWorkspaceDir.replace(/\\/g, "/")
: rosWorkspaceDir;
yield execBashCommand(`find "${posixRosWorkspaceDir}" -type d -and -name "${repo["repo"]}" | xargs rm -rf`, commandPrefix);
yield execBashCommand(`find "${posixRosWorkspaceDir}" -type d -and -name "${repo["repo"]}" | xargs rm -rf`);
// The repo file for the repository needs to be generated on-the-fly to
// incorporate the custom repository URL and branch name, when a PR is
// being built.
Expand All @@ -3394,20 +3384,20 @@ function run() {
url: 'https://${tokenAuth}github.com/${repoFullName}.git'
version: '${commitRef}'`;
fs_1.default.writeFileSync(repoFilePath, repoFileContent);
yield execBashCommand("vcs import --force --recursive src/ < package.repo", commandPrefix, options);
yield execBashCommand("vcs import --force --recursive src/ < package.repo", undefined, options);
// Remove all repositories the package under test does not depend on, to
// avoid having rosdep installing unrequired dependencies.
yield execBashCommand(`diff --new-line-format="" --unchanged-line-format="" <(colcon list -p) <(colcon list --packages-up-to ${packageNameList.join(" ")} -p) | xargs rm -rf`, commandPrefix, options);
yield execBashCommand(`diff --new-line-format="" --unchanged-line-format="" <(colcon list -p) <(colcon list --packages-up-to ${packageNameList.join(" ")} -p) | xargs rm -rf`, undefined, options);
// Install ROS dependencies for each distribution being sourced
if (targetRos1Distro) {
yield execBashCommand(`DEBIAN_FRONTEND=noninteractive RTI_NC_LICENSE_ACCEPTED=yes rosdep install -r --from-paths src --ignore-src --rosdistro ${targetRos1Distro} -y || true`, commandPrefix, options);
yield execBashCommand(`DEBIAN_FRONTEND=noninteractive RTI_NC_LICENSE_ACCEPTED=yes rosdep install -r --from-paths src --ignore-src --rosdistro ${targetRos1Distro} -y || true`, undefined, options);
}
if (targetRos2Distro) {
yield execBashCommand(`DEBIAN_FRONTEND=noninteractive RTI_NC_LICENSE_ACCEPTED=yes rosdep install -r --from-paths src --ignore-src --rosdistro ${targetRos2Distro} -y || true`, commandPrefix, options);
yield execBashCommand(`DEBIAN_FRONTEND=noninteractive RTI_NC_LICENSE_ACCEPTED=yes rosdep install -r --from-paths src --ignore-src --rosdistro ${targetRos2Distro} -y || true`, undefined, options);
}
if (colconMixinName !== "" && colconMixinRepo !== "") {
yield execBashCommand(`colcon mixin add default '${colconMixinRepo}'`, commandPrefix);
yield execBashCommand("colcon mixin update default", commandPrefix);
yield execBashCommand(`colcon mixin add default '${colconMixinRepo}'`);
yield execBashCommand("colcon mixin update default");
}
let extra_options = [];
if (colconMixinName !== "") {
Expand All @@ -3430,37 +3420,53 @@ function run() {
// ament_cmake should handle this automatically, but we are seeing cases
// where this does not happen. See issue #26 for relevant CI logs.
core.addPath(path.join(rosWorkspaceDir, "install", "bin"));
// Source any installed ROS distributions if they are present
let colconCommandPrefix = "";
if (isLinux) {
if (targetRos1Distro) {
const ros1SetupPath = `/opt/ros/${targetRos1Distro}/setup.sh`;
if (fs_1.default.existsSync(ros1SetupPath)) {
colconCommandPrefix += `source ${ros1SetupPath} && `;
}
}
if (targetRos2Distro) {
const ros2SetupPath = `/opt/ros/${targetRos2Distro}/setup.sh`;
if (fs_1.default.existsSync(ros2SetupPath)) {
colconCommandPrefix += `source ${ros2SetupPath} && `;
}
}
}
let colconBuildCmd = `colcon build --event-handlers console_cohesion+ \
--packages-up-to ${packageNameList.join(" ")} \
${extra_options.join(" ")} \
--cmake-args ${extraCmakeArgs}`;
if (!isWindows) {
colconBuildCmd = colconBuildCmd.concat(" --symlink-install");
}
yield execBashCommand(colconBuildCmd, commandPrefix, options);
yield execBashCommand(colconBuildCmd, colconCommandPrefix, options);
// ignoreReturnCode is set to true to avoid having a lack of coverage
// data fail the build.
const colconLcovInitialCmd = "colcon lcov-result --initial";
yield execBashCommand(colconLcovInitialCmd, commandPrefix, {
yield execBashCommand(colconLcovInitialCmd, colconCommandPrefix, {
cwd: rosWorkspaceDir,
ignoreReturnCode: true,
});
const colconTestCmd = `colcon test --event-handlers console_cohesion+ \
--pytest-with-coverage --return-code-on-test-failure \
--packages-select ${packageNameList.join(" ")} \
${extra_options.join(" ")}`;
yield execBashCommand(colconTestCmd, commandPrefix, options);
yield execBashCommand(colconTestCmd, colconCommandPrefix, options);
// ignoreReturnCode, check comment above in --initial
const colconLcovResultCmd = `colcon lcov-result \
--filter ${coverageIgnorePattern} \
--packages-select ${packageNameList.join(" ")}`;
yield execBashCommand(colconLcovResultCmd, commandPrefix, {
yield execBashCommand(colconLcovResultCmd, colconCommandPrefix, {
cwd: rosWorkspaceDir,
ignoreReturnCode: true,
});
const colconCoveragepyResultCmd = `colcon coveragepy-result \
--packages-select ${packageNameList.join(" ")}`;
yield execBashCommand(colconCoveragepyResultCmd, commandPrefix, options);
yield execBashCommand(colconCoveragepyResultCmd, colconCommandPrefix, options);
core.setOutput("ros-workspace-directory-name", rosWorkspaceName);
}
catch (error) {
Expand Down
60 changes: 32 additions & 28 deletions src/action-ros-ci.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,21 +166,10 @@ async function run() {
return;
}

// Source any installed ROS binary distribution, safely creating an empty setup file if it is not present
let commandPrefix = "";
if (isLinux) {
if (targetRos1Distro) {
commandPrefix += `mkdir -p /opt/ros/${targetRos1Distro} && touch /opt/ros/${targetRos1Distro}/setup.sh && source /opt/ros/${targetRos1Distro}/setup.sh && `;
}
if (targetRos2Distro) {
commandPrefix += `mkdir -p /opt/ros/${targetRos2Distro} && touch /opt/ros/${targetRos2Distro}/setup.sh && source /opt/ros/${targetRos2Distro}/setup.sh && `;
}
}

// rosdep on Windows does not reliably work on Windows, see
// rosdep does not reliably work on Windows, see
// ros-infrastructure/rosdep#610 for instance. So, we do not run it.
if (!isWindows) {
await execBashCommand("rosdep update", commandPrefix);
await execBashCommand("rosdep update");
}

// Reset colcon configuration.
Expand All @@ -201,7 +190,7 @@ async function run() {
for (let vcsRepoFileUrl of vcsRepoFileUrlListResolved) {
await execBashCommand(
`curl ${curlFlags} '${vcsRepoFileUrl}' | vcs import --force --recursive src/`,
commandPrefix,
undefined,
options
);
}
Expand All @@ -215,8 +204,7 @@ async function run() {
? rosWorkspaceDir.replace(/\\/g, "/")
: rosWorkspaceDir;
await execBashCommand(
`find "${posixRosWorkspaceDir}" -type d -and -name "${repo["repo"]}" | xargs rm -rf`,
commandPrefix
`find "${posixRosWorkspaceDir}" -type d -and -name "${repo["repo"]}" | xargs rm -rf`
);

// The repo file for the repository needs to be generated on-the-fly to
Expand All @@ -241,7 +229,7 @@ async function run() {
fs.writeFileSync(repoFilePath, repoFileContent);
await execBashCommand(
"vcs import --force --recursive src/ < package.repo",
commandPrefix,
undefined,
options
);

Expand All @@ -251,32 +239,31 @@ async function run() {
`diff --new-line-format="" --unchanged-line-format="" <(colcon list -p) <(colcon list --packages-up-to ${packageNameList.join(
" "
)} -p) | xargs rm -rf`,
commandPrefix,
undefined,
options
);

// Install ROS dependencies for each distribution being sourced
if (targetRos1Distro) {
await execBashCommand(
`DEBIAN_FRONTEND=noninteractive RTI_NC_LICENSE_ACCEPTED=yes rosdep install -r --from-paths src --ignore-src --rosdistro ${targetRos1Distro} -y || true`,
commandPrefix,
undefined,
options
);
}
if (targetRos2Distro) {
await execBashCommand(
`DEBIAN_FRONTEND=noninteractive RTI_NC_LICENSE_ACCEPTED=yes rosdep install -r --from-paths src --ignore-src --rosdistro ${targetRos2Distro} -y || true`,
commandPrefix,
undefined,
options
);
}

if (colconMixinName !== "" && colconMixinRepo !== "") {
await execBashCommand(
`colcon mixin add default '${colconMixinRepo}'`,
commandPrefix
`colcon mixin add default '${colconMixinRepo}'`
);
await execBashCommand("colcon mixin update default", commandPrefix);
await execBashCommand("colcon mixin update default");
}

let extra_options: string[] = [];
Expand All @@ -302,19 +289,36 @@ async function run() {
// where this does not happen. See issue #26 for relevant CI logs.
core.addPath(path.join(rosWorkspaceDir, "install", "bin"));

// Source any installed ROS distributions if they are present
let colconCommandPrefix = "";
if (isLinux) {
if (targetRos1Distro) {
const ros1SetupPath = `/opt/ros/${targetRos1Distro}/setup.sh`;
if (fs.existsSync(ros1SetupPath)) {
colconCommandPrefix += `source ${ros1SetupPath} && `;
}
}
if (targetRos2Distro) {
const ros2SetupPath = `/opt/ros/${targetRos2Distro}/setup.sh`;
if (fs.existsSync(ros2SetupPath)) {
colconCommandPrefix += `source ${ros2SetupPath} && `;
}
}
}

let colconBuildCmd = `colcon build --event-handlers console_cohesion+ \
--packages-up-to ${packageNameList.join(" ")} \
${extra_options.join(" ")} \
--cmake-args ${extraCmakeArgs}`;
if (!isWindows) {
colconBuildCmd = colconBuildCmd.concat(" --symlink-install");
}
await execBashCommand(colconBuildCmd, commandPrefix, options);
await execBashCommand(colconBuildCmd, colconCommandPrefix, options);

// ignoreReturnCode is set to true to avoid having a lack of coverage
// data fail the build.
const colconLcovInitialCmd = "colcon lcov-result --initial";
await execBashCommand(colconLcovInitialCmd, commandPrefix, {
await execBashCommand(colconLcovInitialCmd, colconCommandPrefix, {
cwd: rosWorkspaceDir,
ignoreReturnCode: true,
});
Expand All @@ -323,20 +327,20 @@ async function run() {
--pytest-with-coverage --return-code-on-test-failure \
--packages-select ${packageNameList.join(" ")} \
${extra_options.join(" ")}`;
await execBashCommand(colconTestCmd, commandPrefix, options);
await execBashCommand(colconTestCmd, colconCommandPrefix, options);

// ignoreReturnCode, check comment above in --initial
const colconLcovResultCmd = `colcon lcov-result \
--filter ${coverageIgnorePattern} \
--packages-select ${packageNameList.join(" ")}`;
await execBashCommand(colconLcovResultCmd, commandPrefix, {
await execBashCommand(colconLcovResultCmd, colconCommandPrefix, {
cwd: rosWorkspaceDir,
ignoreReturnCode: true,
});

const colconCoveragepyResultCmd = `colcon coveragepy-result \
--packages-select ${packageNameList.join(" ")}`;
await execBashCommand(colconCoveragepyResultCmd, commandPrefix, options);
await execBashCommand(colconCoveragepyResultCmd, colconCommandPrefix, options);

core.setOutput("ros-workspace-directory-name", rosWorkspaceName);
} catch (error) {
Expand Down

0 comments on commit 875dfcc

Please sign in to comment.